i.MX RT Knowledge Base

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

i.MX RT Knowledge Base

Discussions

Sort by:
How to load MDK RAM app to the RT1170 external flash 1. Abstract This guide is requested by our end customer, he wants to realize the MDK project RAM code download to the MIMXRT1170 external QSPI flash. So, based on the NXP RT1170 SDK, and the MIMXRT1170-EVK board, generate the MDK project, reallocate the app image, generate the image, and use the tool to download the code to the external flash. 2. App image prepare 2.1 Generate one SDK MDK standalone project Open the SDK_2_15_000_MIMXRT1170-EVK webpage: https://mcuxpresso.nxp.com/en/builder?hw=MIMXRT1170-EVK Download the SDK, and generate one MDK standalone project: Fig 1 Fig 2 After downloading, we will get the MIMXRT1170-EVK-iled_blinky_cm7.zip, which is the MDK project. 2.2 MDK project image reallocation As the RAM image is the none-xip image, normally to the IDE, can’t download to the flash directly, as the debug is in the RAM. If want to download to the flash, we can generate the app image, then use the tool to program it to the external flash. Normally, none-xip image, the IVT offset is 0X400, so we need to reallocate the image start address, here, we can use 0X2000 as the app entry address. Fig 3 ITCM default size is 256K=0X4000, so modify the linker file-> scf file like this: Fig 4 Now, to generate the hex and bin image file, which is used for the tool downloading. Fig 5 To build the bin file command: $K\ARM\ARMCC\bin\fromelf.exe --bin --output=debug\@L.bin !L Fig 6   Building, you can find the file in the folder: MIMXRT1170-EVK-iled_blinky_cm7\iled_blinky_cm7\debug Fig 7 2.3 MDK project debug after reallocation After the image reallocation, some customer may still need the MDK RAM project can do the debugging, here, also need to modify the debug .ini file. The Setup also need to change the SP, PC and Vector table offset register address. Fig 8 Then build and debug the code, we can find it can enter the ram image debug mode: Fig 9 3. App image download We can use the MCUBootUtility Tool to download the code: https://github.com/JayHeng/NXP-MCUBootUtility/releases/tag/v6.1.0 the related user manual is: https://github.com/JayHeng/NXP-MCUBootUtility Download the tool. MIMXRT1170-EVK enter the serial download mode by changing SW1: 1-OFF,2-OFF,3-OFF,4-ON Power off and power on the board again, find another USB cable to connect the J20 USB1 interface. Then, use the MCUBootutility to connect the board: Fig 10 After connection, select the MDK project generated .hex file: Fig 11 Press the All-in-One-Action button, to download the code, this is the downloaded result: Fig 12 Press the “Reset device” button to exit the tool. Then MIMXRT1170-EVK board change SW1: 1-OFF, 2-OFF, 3-ON,4-OFF Press the EVK on board reset button, SW4, you will find the LED is blinking, it means the MDK RAM project already download to the external QSPI flash, and boot OK.
View full article
1 Introduction RT1060 MCUXpresso SDK provide the ota_bootloader project, download link: https://mcuxpresso.nxp.com/en/welcome ota_bootloader path: SDK_2_10_0_EVK-MIMXRT1060\boards\evkmimxrt1060\bootloader_examples\ota_bootloader  this ota_bootloader can let the customer realize the on board app update, the RT1060 OTA bootloader mainly have the two functions: ISP method update APP Provide the API to the customer, can realize the different APP swap and rollback function ISP method is from the flashloader, the flashloader put the code in the internal RAM, when use it, normally RT chip need to enter the serial download mode, and use the sdphost download the flashloader to the internal RAM, then run it to realize the ISP function. But OTA_bootloader will put the code in the flash directly, RT chip can run it in the internal boot mode directly, each time after chip reset, the code will run the ota_bootloader at first, this time, customer can use the blhost to communicate the RT chip with UART/USB HID directly to download the APP code. So, to the ISP function in the OTA_bootloader, customer also can use it as the ISP secondary bootloader to update the APP directly. Then reset after the 5 seconds timeout, if the APP area is valid, code will jump to the APP and run APP. To the ota_bootloader swap and rollback function, customer can use the provided API in the APP directly to realize the APP update, run the different APP, swap and rollback to the old APP.    This document will give the details about how to use the ota_bootloader ISP function to update the APP, how to modify the customer application to match the ota_bootloader, how to resolve the customer APP issues which need to use the SDRAM with the ota_bootloader, how to use the ota_bootloader API to realize the swap and rollback function, and the related APP prepare. 2 OTA bootloader ISP usage Some customers need the ISP secondary bootloader function, as the flashloader need to put in the internal RAM, so customer can use the ota_bootloader ISP function realize the secondary bootloader requirement, to this method, customer mainly need to note two points: 1) APP need to add the ota_header to meet the ota_bootloader demand. 2) APP use the SDRAM, ota_bootloader need to add DCD memory  2.1 application modification OTA_bootloader located in the flash from 0x60000000, APP locate from 0x60040000. We can find this from the ota_bootloader bootloader_config.h file: #define BL_APP_VECTOR_TABLE_ADDRESS (0x60040000u) From 0x60040000, the first 0X400 should put the ota_header, then the real APP code is put from 0x60040400. Now, take the SDK evkmimxrt1060_iled_blinky project as an example, to modify it to match the ota_bootloader. Application code need to add these files: ota_bootloader_hdr.c, ota_bootloader_board.h, ota_bootloader_supp.c, ota_bootloader_supp.h These files can be found from the evkmimxrt1060_lwip_httpssrv_ota project, put the above files in the led_blinky source folder. 2.1.1 memory modification    APP memory start address modify from 0x60000000 to 0x60040000, which is the ota_bootloader defined address。 Fig 1 2.1.2 ota_hdr related files add   In the led_blinky project source folder, add the mentioned ota_bootloader related files. Fig 2 2.1.3 linker file modification In the evkmimxrt1060_iled_blinky_debug.ld, add boot_hdr, length is 0X400. We can use the MCUXpresso IDE linkscripts folder, add the .ldt files to modify the linker file. Here, in the project, add one linkscripts folder, add the boot_hdr_MIMXRT1060.ldt file, build . Fig 3 After the build, we can find the ld file already add the ota_header in the first 0x400 range. Fig 4 The above is the generated evkmimxrt1060_iled_blinky_ota_0x60040000.bin file, we can find already contains the boot_hdr. From offset 0x400, will put the real APP code. 2.2 ISP test related command Test board is MIMXRT1060-EVK, download the evkmimxrt1060_ota_bootloader project at first, can use the mcuxpresso IDE download it directly, then press the reset button, put the blhost and evkmimxrt1060_iled_blinky_ota_0x60040000.bin in the same folder, use the following command:   blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0 blhost.exe -t 2048000 -u 0x15a2,0x0073 -j -- flash-erase-region 0x60040000 0x6000 9 blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- write-memory 0x60040000 evkmimxrt1060_iled_blinky_ota_0x60040000.bin blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- read-memory 0x60040000 0x6000 flexspiNorCfg.dat 9 Fig 5 After the download is finished, press the reset, wait 5 seconds, it will jump to the app, we can find the MIMXRT1060-EVK on board led is blinking. This method realize the flash ISP bootloader downloading and the app working. The above command is using the USB HID to download, if need to use the UART, also can use command like this: blhost.exe -t 50000 -p COM45,19200 -j -- get-property 1 0 blhost.exe -t 50000 -p COM45,19200 -j -- flash-erase-region 0x60040000 0x6000 9 blhost.exe -t 50000 -p COM45,19200 -j -- write-memory 0x60040000 evkmimxrt1060_iled_blinky_ota_0x60040000.bin blhost.exe -t 50000 -p COM45,19200 -j -- read-memory 0x60040000 0x6000 flexspiNorCfg.dat 9 To the UART communication, as the ota_bootloader auto baud detect issues, it’s better to use the baudrate not larger than 19200bps, or in the ota_bootloader code, define the fixed baudrate, eg, 115200. 2.3 Bootloader DCD consideration Some customer use the ota_bootloader to associate with their own application, which is used the external SDRAM, and find although the downloading works, but after boot, the app didn’t run successfully. In the APP code, it add the DCD configuration, but as the ota_bootloader already put in the front of the QSPI, app will use the ota_hdr, which will delete the dcd part, so, to this situation, customer can add the dcd in the ota_bootloader. The SDK ota_bootloader didn’t add the dcd part in default. Now, modify the ota_bootloader at first, then prepare the sdram app and test it. 2.3.1 Ota_bootloader add dcd 2.3.1.1 add dcd files   ota_bootloader add dcd.c dcd.h, these two files can be found from the SDK hello_world project. Copy these two files to the ota_bootloader board folder. From the dcd.c code, we can see, dcd_data[] array is put in the “.boot_hdr.dcd_data” area, and it need to define the preprocessor: XIP_BOOT_HEADER_DCD_ENABLE=1 2.3.1.2 add dcd linker code   Modify the mcuxpresso IDE ld files, and add the dcd range.    .ivt : AT(ivt_begin) { . = 0x0000 ; KEEP(* (.boot_hdr.ivt)) /* ivt section */ . = 0x0020 ; KEEP(* (.boot_hdr.boot_data)) /* boot section */ . = 0x0030 ; KEEP(*(.boot_hdr.dcd_data)) __boot_hdr_end__ = ABSOLUTE(.) ; . = 0x1000 ; } > m_ivt Fig 6 0x60001000 : IVT 0x6000100c : DCD entry point 0x60001020 : boot data 0x60001030 : DCD detail data 2.3.1.3 add IVT dcd entry point   ota_bootloader->MIMXRT1062 folder->hardware_init_MIMXRT1062.c,modify the image_vector_table, fill the DCD address to the dcdc_data array address as the dcd entry point. Fig 7 Until now, we finish the ota_bootloader dcd add, build the project, generate the image, we can find, DCD already be added to the ota_bootloader image. Fig 8 DCD entry point in the IVT and the DCD data is correct, we can burn this modified ota_bootloader to the MIMXRT1060-EVK board. 2.3.2 SDRAM app prepare Still based on the evkmimxrt1060_iled_blinky project, just put some function in the SDRAM. From memory, we can find, the SRAM is in the RAM4: Fig 9 In the led_blinky.c, add this header: #include <cr_section_macros.h> Then, put the systick delay code to the RAM4 which is the SDRAM area. __RAMFUNC(RAM4) void SysTick_DelayTicks(uint32_t n) { g_systickCounter = n; while (g_systickCounter != 0U) { } } Now, we already finish the simple SDRAM app, we also can test it, and put the breakpoint in the SysTick_DelayTicks, we can find the address is also the SDRAM related address, generate the evkmimxrt1060_iled_blinky1_SDRAM_0x60040000.bin. If use the old ota_bootloader to download this .bin, we can find the led is not blinking. 2.3.3 Test result Command refer to chapter 2.2 ISP test related command, download the evkmimxrt1060_iled_blinky1_SDRAM_0x60040000.bin with the new modified ota_bootloader project, we can find, after reset, the led will blink. So the SDRAM app works with the modified ota_bootloader. 3 OTA bootloader swap and rollback OTA bootloader can realize the swap and rollback function, this part will test the ota_bootloader swap and rollback, prepare two apps and download to the different partition area, then use the UART input char to select the swap or rollback function, to check the which app is running. 3.1  memory map ota bootloader memory information. Fig 10 The above map is based on the external 8Mbyte QSPI flash. OTA bootloader: RT SDK ota bootloader code Boot meta 0: contains 3 partition start address, size etc. information, ISP peripheral information. Boot meta 1: contains 3 partition start address, size etc. information, ISP peripheral information. Swap meta 0: bootloader will use meta data to do the swap operation Swap meta 1: bootloader will use meta data to do the swap operation Partition 1: APP1 location Partition 2: APP2 location Scratch part: APP1 backup location, start point is before 0x60441000, which is enough to put APP1 and multiple sector size, eg, APP1 is 0X5410, sector size is 0x1000, APP1 need 6 sectors, so the scratch start address is 0x60441000-0x6000=0x43b000. User data: user used data area 3.2 swap and rollback basic Fig11  The APP1 and APP2 put in the partition1 and partition2 need to contains the ota_header which meet the bootloader demand, bootloader will check the APP CRC, if it passed, then will boot the app, otherwise, it will enter the ISP mode. Partition2 image need to has the valid header, otherwise, swap will be failed.   Swap function will erase partition2 scratch area, then put the partition1 code to the scratch, erase the partition 1 position, and write the partition 2 image to the partition1 position.   Rollback function will run the previous APP1, erase the partition 2 position, copy the parititon 1 image back to the partition 2, erase partition 1 position, copy partition 2 scratch image back to partition 1. 3.2.1 boot meta boot_meta 0: 0x0x6003c000 size: 0x20c boot_meta 1: 0x0x6003d000 size: 0x20c   OTA bootloader can read boot meta from the two different address, when the two address meta are valid(tag is 'B', 'L', 'M', 'T'), bootloader will choose the bigger version meta. If both meta is not valid, bootloader will copy default boot meta data to the boot meta 0 address.   Boot meta contains 3 partition start address, size information. SDK demo can call bootloader API to find the partition information, then do the image program.   Boot meta also contains the ISP peripheral information, the timeout(5s) information, the structure is: //!@brief Partition information table definitions typedef struct { uint32_t start; //!< Start address of the partition uint32_t size; //!< Size of the partition uint32_t image_state; //!< Active/ReadyForTest/UnderTest uint32_t attribute; //!< Partition Attribute - Defined for futher use uint32_t reserved[12]; //!< Reserved for future use } partition_t; //!@brief Bootloader meta data structure typedef struct { struct { uint32_t wdTimeout; uint32_t periphDetectTimeout; uint32_t enabledPeripherals; uint32_t reserved[12]; } features; partition_t partition[kPartition_Max];//16*4*7 bytes uint32_t meta_version; uint32_t patition_entries; uint32_t reserved0; uint32_t tag; } bootloader_meta_t;   3.2.2 swap meta Swap meta 0 : 0x6003e000, size 0x50 Swap meta 1 : 0x6003f000, size 0x50    OTA bootloader will read the swap meta from 2 different place, if it is not valid, bootloader will set the default data to swap meta 0(0x6003e000). If both image are valid, bootloader will choose the bigger version meta.    Bootloader will refer to the meta data to do the swap operation, sometimes, after reset, meta data will be modified automatically. It mainly relay on the swap_type: kSwapType_ReadyForTest :After reset, do swap operation. Modify meta swap_type to kSwapType_Test. Reset, as the meta data is kSwapType_Test, bootloader can do the rollback. kSwapType_Test : After reset, do rollback after operation, swap_type change to kSwapType_None.  kSwapType_Rollback bootloader will write kSwapType_Test to the meta, after reset, bootloader will refer to kSwapType_Test to do the operation.  kSwapType_Permanent After reset, modify meta data to kSwapType_Permanent, then the APP will boot with partition 1. Swap structure: //!@brief Swap progress definitions typedef struct { uint32_t swap_offset; //!< Current swap offset uint32_t scratch_size; //!< The scratch area size during current swapping uint32_t swap_status; // 1 : A -> B scratch, 2 : B -> A uint32_t remaining_size; //!< Remaining size to be swapped } swap_progress_t; typedef struct { uint32_t size; uint32_t active_flag; } image_info_t; //!@brief Swap meta information, used for the swapping operation typedef struct { image_info_t image_info[2]; //!< Image info table #if !defined(BL_FEATURE_HARDWARE_SWAP_SUPPORTED) || (BL_FEATURE_HARDWARE_SWAP_SUPPORTED == 0) swap_progress_t swap_progress; //!< Swap progress #endif uint32_t swap_type; //!< Swap type uint32_t copy_status; //!< Copy status uint32_t confirm_info; //!< Confirm Information uint32_t meta_version; //!< Meta version uint32_t reserved[7]; //!< Reserved for future use uint32_t tag; } swap_meta_t; 3.3 Common used API Bootloader provide the API for the customer to use it, the common used API are: 3.3.1 update_image_state   update swap meta data, before update, it will check the partition1 image valid or not, if image is not valid, swap meta data will not be updated, and return failure. 3.3.2 get_update_partition_info   get partition information, then define the image program address. 3.3.3 get_image_state   get the current boot image status. None/permanent/UnderTest 3.4  Swap rollback APP prepare Prepare two APPs: APP1 and APP2 bin file, and use the USB HID download to the partition1 and paritition 2. After reset, run APP1 in default, then use the COM input to select the swap and rollback function. Code is: int main(void) { char ch; status_t status; /* Board pin init */ BOARD_InitPins(); BOARD_InitBootClocks(); /* Update the core clock */ SystemCoreClockUpdate(); BOARD_InitDebugConsole(); PRINTF("\r\n------------------hello world + led blinky demo 2.------------------\r\n"); PRINTF("\r\nOTA bootloader test...\r\n" "1 - ReadyForTest\r\n" "3 - kSwapType_Permanent\r\n" "4 - kSwapType_Rollback\r\n" "5 - show image state\r\n" "6 - led blinking for 5times\r\n" "r - NVIC reset\r\n"); // show swap state in swap meta get_image_swap_state(); /* Set systick reload value to generate 1ms interrupt */ if (SysTick_Config(SystemCoreClock / 1000U)) { while (1) { } } while(1) { ch = GETCHAR(); switch(ch) { case '1': status = bl_update_image_state(kSwapType_ReadyForTest); PRINTF("update_image_state to kSwapType_ReadyForTest status: %i\n", status); if (status != 0) PRINTF("update_image_state(kSwapType_ReadyForTest): failed\n"); else NVIC_SystemReset(); break; case '3': status = bl_update_image_state(kSwapType_Permanent); PRINTF("update_image_state to kSwapType_Permanent status: %i\n", status); if (status != 0) PRINTF("update_image_state(kSwapType_Permanent): failed\n"); else NVIC_SystemReset(); break; case '4': status = bl_update_image_state(4); // PRINTF("update_image_state to kSwapType_Rollback status: %i\n", status); if (status != 0) PRINTF("update_image_state(kSwapType_Rollback): failed\n"); else NVIC_SystemReset(); break; case '5': // show swap state in swap meta get_image_swap_state(); break; case '6': Led_blink10times(); break; case 'r': NVIC_SystemReset(); break; } } } When download the APP, need to use the correct ota_header in the first 0x400 area, otherwise, swap will failed. const boot_image_header_t ota_header = { .tag = IMG_HDR_TAG, .load_addr = ((uint32_t)&ota_header) + BL_IMG_HEADER_SIZE, .image_type = IMG_TYPE_XIP, .image_size = 0, .algorithm = IMG_CHK_ALG_CRC32, .header_size = BL_IMG_HEADER_SIZE, .image_version = 0, .checksum = {0xFFFFFFFF}, }; This is a correct sample: Fig 12 Image size and checksum need to use the real APP image information, in the attached file, provide one image_header_padding.exe, it can input the none ota header image, then it will output the whole image which add the ota_header contains the image size and the image crc data in the first 0x400 range. 3.5 Test steps and result Prepare the none header APP1 evkmimxrt1060_APP1_0X60040400.bin, APP2 image evkmimxrt1060_APP2_0X60240400.bin, and put blhost.exe, image_header_padding.exe in the same folder. APP1 and APP2 just the printf version is different, one is version1, another is version2. Printf result: hello world + led blinky demo 1 hello world + led blinky demo 2 Attached OTAtest folder is used for test, but need to download the blhost.exe from the below link, and copy the blhost.exe to the OTAtest folder. https://www.nxp.com/webapp/sps/download/license.jsp?colCode=blhost_2.6.6&appType=file1&DOWNLOAD_ID=null Then run the following bat command: image_header_padding.exe evkmimxrt1060_APP1_0X60040400.bin 0x60040400 sleep 20 blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0 sleep 20 blhost.exe -u -t 1000000 -- flash-erase-region 0x6003c000 0x4000 sleep 50 blhost -u -t 5000 -- flash-erase-region 0x60040000 0x10000 sleep 50 blhost -u -t 5000 -- write-memory 0x60040000 boot_img_crc32.bin sleep 100 image_header_padding.exe evkmimxrt1060_APP2_0X60240400.bin 0x60040400 sleep 20 blhost -u -t 5000 -- flash-erase-region 0x60240000 0x10000 sleep 50 blhost -u -t 5000 -- flash-erase-region 0x6043b000 0x10000 sleep 50 blhost -u -t 5000 -- write-memory 0x60240000 boot_img_crc32.bin sleep 100 pause The function is to generate the APP1 with the correct ota_header, erase parititon 1,program APP1 to partition 1, generate the APP2 with the correct ota_header, erase partition 2 and scratch area, program APP2 to partition 2, Run the .bat file should in 5 seconds after reset, then use the ISP to connect it: blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0 ota_bootloader can use the ota_bootloader project download directly to the 0X60000000 area. After downloading, reset the chip, and wait for 5 seconds, the APP will run. This is the test result: Fig 13 From the test result, we can find, in the first time boot, APP1 running, image state: none Input 1, do the swap, will find the APP2 running, image state: undertest Input 3, select permanent, reset will find, still APP2 running, image state: permanent Input 4, choose rollback, reset will find APP1 running, image states: none Until now, finish the swap and rollback function. Input 6, will find the APP contains the SDRAM led blinky is working.          
View full article
The RT1170 supports the ability to trigger dual ADC’s in SyncMode or AsyncMode via the ADC External Trigger Control (ADC_ETC): In SyncMode, ADC1 and ADC2 are controlled by the same trigger source. In AsyncMode, ADC1 and ADC2 are controlled by separate trigger source. In AsyncMode (TRIGa_CTRL[SYNC_MODE]==0), the ADC conversion clock frequency maximum is 88 MHz, but in SyncMode (TRIGa_CTRL[SYNC_MODE]==1), the ADC conversion clock frequency must be constraint to a lower frequency due to switching noise inherent to its design architecture.  Reducing the conversion clock frequency reduces the switching noise that is observed. NXP is currently conducting further characterization in order to specify the maximum frequency of conversion in SyncMode across process, voltage, and temperature.  However, on typical samples at room temperature 60 MHz is the maximum frequency.
View full article
RT1170 SBL ISP download app for remap function 1. Abstract Previously wrote a post about using the official SBL ISP method to download the APP: RT1170 SBL ISP download SDRAM APP Recently, a customer also needs to use RT1170 SBL ISP to download code, but the code app that needs to be downloaded is based on MCUXpresso IDE, which generates a bin file and can be programmed to different locations in the flash, and then use remap to run the corresponding app. Regarding remap, we can know from the SBL documentation that RT1170 can directly support it: Fig 1 Usually, if combined with SFW for SD card, cloud and other app updates, the remap function can be directly supported. Because SFW currently only supports two IDEs: IAR and MDK, and does not support MCUXPresso IDE, it is not particularly convenient for customers to use MCUXPresso to develop apps. Moreover, customers do not need to use an SD card or network cloud to update the code. SBL's ISP Updates are enough. So how to use SBL to implement the remap function of two MCUXpresso apps? For MCUXpresso App, you can use one project, so you only need to modify the content to identify different apps and burn them to different flash addresses. The specific implementation methods and steps are given below. The spatial structure of SBL, APP1, and APP2 codes is as follows: Fig 2 2. SBL operation and modification 2.1 SBL configuration and downloading Refer to the doc chapter 2.1: RT1170 SBL ISP download SDRAM APP Generate the related sbl_iar project. 2.2 SBL add remap code Opern sbl project file: sbl-master\boot\sbl_boot.c int sbl_boot_main(void) code modified like this: int sbl_boot_main(void) { char ch = 0; struct image_header br_hdr1 = { .ih_hdr_size = 0x2000 }; struct boot_rsp rsp = { .br_hdr = &br_hdr1, .br_flash_dev_id = 1, .br_image_off = 0x80000 }; int rc = 0; #ifdef CONFIG_BOOT_SIGNATURE #if defined(SOC_IMXRTYYYY_SERIES) || defined(SOC_LPC55S69_SERIES) CRYPTO_InitHardware(); #endif #endif sbl_flash_init(); #ifdef TEST_FUNCTION enable_image(Permanent_mode); #endif BOOT_LOG_INF("Bootloader Version %s", BOOTLOADER_VERSION); os_heap_init(); BOOT_LOG_INF("remap or not:Y/N\r\n\r\n"); ch = GETCHAR(); BOOT_LOG_INF("input=%c,\r\n\r\n",ch); if((ch == 'Y') || (ch == 'y')) { BOOT_LOG_INF("With remap!\r\n\r\n"); SBL_EnableRemap(BOOT_FLASH_ACT_APP, BOOT_FLASH_ACT_APP+FLASH_AREA_IMAGE_1_SIZE, FLASH_AREA_IMAGE_1_SIZE); } else if((ch == 'N') || ((ch == 'n') )) { BOOT_LOG_INF("Without remap!\r\n\r\n"); SBL_DisableRemap(); } else { BOOT_LOG_INF("Without remap!\r\n\r\n"); } #ifdef SINGLE_IMAGE rc = boot_single_go(&rsp); #else #ifdef SOC_REMAP_ENABLE rc = boot_remap_go(&rsp); #else rc = boot_go(&rsp); #endif #endif /* SINGLE_IMAGE*/ if (rc != 0) { while (1) { BOOT_LOG_ERR("Unable to find bootable image"); SDK_DelayAtLeastUs(3000000, BOARD_BOOTCLOCKRUN_CORE_CLOCK); } } BOOT_LOG_INF("Bootloader chainload address offset: 0x%x", rsp.br_image_off); BOOT_LOG_INF("Reset_Handler address offset: 0x%x", rsp.br_image_off + rsp.br_hdr->ih_hdr_size); BOOT_LOG_INF("Jumping to the image\r\n\r\n"); do_boot(&rsp); BOOT_LOG_ERR("Never should get here"); for (;;); } After modification, build the IAR SBL project, then use the debugger download the sbl to the MIMXRT1170-EVK board. 3. APP prepare Refer to doc chapter 2.2: RT1170 SBL ISP download SDRAM APP In order to know the detail app, we can use the hello_world project, and modify the code like the following: int main(void) { char ch; /* Init board hardware. */ BOARD_ConfigMPU(); BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); PRINTF("hello world1->real addr is 0X30100000\r\n"); //app1 // PRINTF("hello world2->real addr is 0X30200000\r\n");//app2 while (1) { ch = GETCHAR(); PUTCHAR(ch); } } Use app1 printf code, to generate the hello_world1.bin,then add the secure header which match to the SBL, generate the hello_app1.bin. Use app2 printf code, to generate the hello_world2.bin,then add the secure header which match to the SBL, generate the hello_app2.bin. Now, give the details how to generate the related secure app: Open sbl-master\target\evkmimxrt1170\env.bat: Change the path to: cd ..\..\component\secure\mcuboot\scripts copy the mcuxpresso project generated bin file:hello_world1.bin and hello_world2.bin to: sbl-master\component\secure\mcuboot\scripts Use the following commander: python imgtool.py sign --key xxxx_priv.pem --align 4 --version "1.1" --header-size 0x400 --pad-header --slot-size 0x100000 --max-sectors 32 hello_world1.bin hello_app1.bin python imgtool.py sign --key xxxx_priv.pem --align 4 --version "1.1" --header-size 0x400 --pad-header --slot-size 0x100000 --max-sectors 32 hello_world2.bin hello_app2.bin to generate the hello_app1.bin, hello_app2.bin. Fig 3 3. Test result Use the MCUbootutility SBL OTA run mode, after board reset, in 5 seconds to connect the board, then burn: hello_app1.bin to 0X30100000 hello_app2.bin to 0X30200000 Fig 4 Fig 5 After downloading, exit MCUBootutility. Reset the board, in the console wait the log appear, then input ‘Y’ or ‘N’ to select which app boots: ‘Y’: remap, APP2 boot ‘N’: without remap, APP1 boot Test result is:   Fig 6 From the test result, we can see the remap function already works OK.  
View full article
This demo code shows how to synchronize the PWM signals with another internal timer or an off-chip source. It allows you to achieve slower PWM frequencies than those that can be achieved with internal clocks as well as that multiple modules and multiple chips can be synchronized to each other. The idea is the following: The QTMR generates a PWM signal (external clock signal) which is routed through the XBAR to clocking the eFlexPWM, and at the same, the external clock signal is routed to an IO PAD in the first MCU. In a second MCU, an IO PAD is routed through the XBAR to clocking the eFlexPWM (see Figure 1).   Figure 1     The demo code (only MCU1 part so far) can me tested using the SDK for EVKB-IMXRT1050 v2.14.0. Probe the PWM signals using an oscilloscope: - At J24-1  GPIO_AD_B0_03  XBAR1_INOUT17 (QTMR PWM signal) - At J24-6  GPIO_SD_B0_00  FLEXPWM1_PWM0_A - At J24-3  GPIO_SD_B0_01  FLEXPWM1_PWM0_B Please remember weld resistors 0Ω at R280 R281.
View full article
RT1050 Boundary Scan test based on lauterbach 1. Abstract Boundary Scan is a method of testing interconnections on circuit boards or internal sub-blocks of circuits. You can also debug and observe the pin status of the integrated circuit, measure the voltage or analyze the sub-modules inside the integrated circuit, and test based on the JTAG interface. NXP officials have provided two good application notes: AN13507 (LPC) and AN12919 (RT). Based on the reference application note test method, this article provides the boundary scan test results for NXP MIMXRT1050-EVK revA1. It can use Lauterbach to connect the chip and perform boundary scan to control the external pins. A script file is also provided. It can realize one-click connection to boundary scan and achieve level control of external pins. 2. RT1050 test details 2.1 Hardware platform Lauterbach:LA3050 MIMXRT1050-EVK rev A1 hardware modification point are as follows: (1)Modify fuse bit 0X460[19], which is DAP_SJC_SWD_SEL, from 0-SWD to 1-JTAG. To modify Fuse, you can enter serial download mode and use MCUbootUtility to connect and modify it. Fig 1 (2)DNP R38 ,R323,R309,R152,R303   (3)  JTAG_MODE connect to 3.3V= on board TP11 connect to J24_8 (4)R35 connect 100K resistor (5)ONOFF pin pull up external 100K resistor to 3.3V,board modification point is SW2 pin3 or pin4 connect 100K resistor and pull up to J24_8.    (6) disconnect J32,J33 which will disconnect the on board debugger, because this test need to use the external Lauterbach.    (7) Use the external Lauterbach connect to JTAG interface J21, the connection picture is:     Fig 2 2.2 Software operation Download Lauderbach's supporting software and install it. After installation, open the TRACE32 ICD Arm USB. If the Lauderbach device is connected, the interface will open successfully. Fig 3 At this time, you can enter the relevant commands in the yellow box in the picture above. Here you need to prepare the .bsdl file of the chip, which is usually placed on the chip introduction page of nxp.com. For example, the link to the bsdl file of RT1050 is https://www.nxp.com/downloads/en/bsdl/RT1050.bsdl You can copy the RT1050.bsdl file to the Lauderbach installation path: C:\T32 Next, enter the following command in the window to open the boundary scan window SYStem.Mode Down BSDL.RESet BSDL.ParkState Select-DR-Scan BSDL.state Here, it will open the window: Fig 4 Click FILE item, input the downloaded RT1050.bsdl , then in the window input the commander: BSDL.SOFTRESET     Fig 5 Click check->BYPASSall,IDCODEall,SAMPLEall, make sure the 3 methods can be passed. It is found here that the following problems are encountered when clicking IDCODEall:   Fig 6 It prompts that the IDCODE read is 188c301d, but the expected IDCODE is 088c301d. So what is the correct IDCODE? You can view RT1050RM:   Fig 7 It can be seen that the currently read 188c301d is in line with RM and is correct. Therefore, the version of bsdl downloaded from the official website needs to be modified. Open the RT1050.bsdl file:   Fig 8 Modify line 408 version from 0000 to 0001,Fig 8 is the modified result. Save, run the above commands again, we can see the current BYPASSall,IDCODEall,SAMPLEall connection result is:   Fig 9 Fig 10 Fig 11 To test the output control situation you need to do: BSDLSET 1.: instructions->EXTEXT, DR mode->Set Write, Filter data-> uncheck intern BSDL.state->Run: check SetAndRun, TwoStepDR,  Click RUN button. BSDLSET 1. Window, you can control the pin output status, eg, control GPIO_AD_B1_06 which is J22_2, control the output level: 1 high, 0 low.   Fig 12 2.3 Automation control command script As can be seen from Section 2.2, single-step operation requires manual typing of commands. In actual testing, the efficiency is very low, so scripting language can be used to directly implement automated command control. Below, we take RT1050 as an example to control the level of the onboard GPIO_AD_B1_06 and J22_2 pins, and use a multimeter to test the high and low levels. In this way, when the TRACE32 software is opened, you only need to open the script directly, enter the debug mode, run it to the end with one click, and view the board Just turn on the light and control the status. Script language, suffix .cmm, step: File->New Script, enter the following script command: ;system setup SYStem.Mode Down SYStem.CPU CortexM7 SYSTEM.CONFIG.DEBUGPORTTYPE JTAG SYStem.JtagClock 1MHz ;BSDL Settings BSDL.RESet BSDL.ParkState Select-DR-Scan BSDL.state ;configure boundary scan chain BSDL.FILE RT1050.bsdl ;Check boundary scan chain BSDL.SOFTRESET BSDL.BYPASSall BSDL.IDCODEall BSDL.SAMPLEall ;Perform Sample test BSDL.RUN BSDL.SetAndRun ON BSDL.TwoStepDR ON BSDL.SET 1. BSDL.SET 1. IR EXTEST BSDL.RUN BSDL.SET 1. PORT GPIO_AD_B1_06 0 BSDL.SET 1. PORT GPIO_AD_B1_06 1 BSDL.SET 1. PORT GPIO_AD_B1_06 0 WAIT 6.s BSDL.SET 1. PORT GPIO_AD_B1_06 1 WAIT 6.s BSDL.SET 1. PORT GPIO_AD_B1_06 0 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 1 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 0 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 1 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 0 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 1 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 0 WAIT 2.s BSDL.SET 1. PORT GPIO_AD_B1_06 1 WAIT 2.s Function: Pull the GPIO_AD_B1_06 pin high and low 6 times, with no delay, delay 5s, delay 2s. After the script is written, save it and debug it.   Fig 13 This is the video for the testing: It can be seen that automatic control of the onboard GPIO_AD_B1_06 and J22_2 pins can be achieved, and there is no disconnection issue when the test delay is greater than 5S, indicating that the BSDL automatic test has been completed so far. If you encounter problems, be sure to pay attention to whether the hardware modification points of the board have been completely modified.   At last, thanks so much for my colleague @leilei_du  and @albert_li 's endless help!    
View full article
RT1170 SBL ISP download SDRAM APP 1. Abstract NXP officially launched SBL and SFW for RT bootloader, which can well meet the requirements for secondary bootloader in regular use. Such as ISP, OTA, encryption and other functions. For specific SBL/SFW situations, you can view the application notes: https://www.nxp.com/docs/en/user-guide/MCUOTASBLSFWUG.pdf This article is mainly based on SBL and uses the ISP method to download user apps. Recently I encountered a case about RT1170 using the SBL ISP function to download APP. After configuring SBL, there is no problem in downloading simple SDK codes such as led_blinky and helloword. However, if you download the SDK GUI demo, such as vglite_examples\vector_freertos code, we find that the boot fails . The same applies to operations such as app offset, and the code size does not exceed 1MByte. However, SDK GUI demo uses SDRAM, so we speculated that it is related to SBL's SDRAM enablement. This article will explain how to use SBL ISP to download an app with SDRAM and make it boots OK. 2. Operation steps 2.1 SBL configuration and programming Firstly, Download SBL source code and unzip it: https://github.com/nxp-mcuxpresso/sbl Download the ARM GCC and install it, here is the gcc-arm-none-eabi-9-2019-q4-major-win32.exe link: https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-win32-sha2.exe?revision=ba95cefa-1880-4932-94d4-ebf30ad3f619&rev=ba95cefa1880493294d4ebf30ad3f619&hash=B2513193FEEED9E850C62399EFF9DA04C0F0A809 The install path is: C:\Program Files (x86)\GNU Tools Arm Embedded\9 2019-q4-major\bin Open \sbl-master\target\evkmimxrt1170\ sblprofile.py, modify EXEC_PATH to the new installed ARM_GCC path: EXEC_PATH   = r'C:\Program Files (x86)\GNU Tools Arm Embedded\9 2019-q4-major\bin' This is the SBL configuration steps: (1). Open \sbl-master\target\evkmimxrt1170\ env.bat input: scons –menuconfig Fig 1 (2). Configure Single image OTA    MCU SBL core->[*]Enable single image function Fig 2 (3) Configure enable SDRAM Fig 3 Fig 4 Fig 5 After configuration, save the .config file, save and exit it. Fig 6 (4) Generate the sbl iar project In the window, input:  scons --ide=iar Then use IAR IDE to open \sbl-master\target\evkmimxrt1170\iar\sbl.eww You can see, the SDRAM DCD has been added now: Fig 7 (5) Configure the secure information Input the following command in the commander window: cd ..\..\component\secure\mcuboot\scripts Switch the commander path, then use the following command to generate the pub key and private key: python imgtool.py keygen -k xxxx_priv.pem -t rsa-2048-sign python imgtool.py getpub -k xxxx_priv.pem -o xxxx_pub.pem -t sign Fig 8 Open the file in path:sbl-master\component\secure\mcuboot\scripts\ xxxx_pub.c, copy the pub key information, and replay it to the file in path: \sbl-master\component\secure\mcuboot\sign-rsa2048-pub.c Then, it will update the SBL pub key information, now open the IAR project: \sbl-master\target\evkmimxrt1170\iar \sbl.eww Build the project, and use the debugger to download the SBL code to the MIMXRT1170-EVK board, I use the EVK on board debugger CMSIS DAP to download the sbl code.   2.2 APP configuration This document app is using the MCUXpresso IDE to import the SDK project: evkmimxrt1170_vector_freertos_cm7 Configure the flash start location to offset address:0X30100400 Fig 9 Delete the FCB and DCD header like this: Fig 10 Build the project, and generate the bin file:evkmimxrt1170_vector_freertos_cm7.bin, copy it to the SBL folder: sbl-master\component\secure\mcuboot\scripts Still in the commander window which you open the env.bat after you change the path previously: python imgtool.py sign --key xxxx_priv.pem --align 4 --version "1.1" --header-size 0x400 --pad-header --slot-size 0x100000 --max-sectors 32 evkmimxrt1170_vector_freertos_cm7.bin app2.bin This will help the app to add the header which matches the SBL requirement, and generate the app2.bin, which is the used app downloading file. 3. Test Result After the above configuration, it already downloads the SBL to the MIMXRT1170-EVK, and prepares the used app which contains the SDRAM, now use the MCUBootutility tool to download the app2.bin. Fig 11 Note, the Tools->Run Mode, should be SBL OTA mode. Find another USB cable to connect the EVK SDP J20 to the PC, after the EVK board reset, within the 5 seconds, connect the board by connection the MCUBootutility button “connect to SBL ISP”, then in the Fig 11, step 4, add the prepared app2.bin, step 3, input the address to: 0X30100000, then use step 5 to download the app. After app is downloaded, reset and exit the connection. Reset the board, wait 5 seconds, you will find the LCD can display the figure, it means the GUI code is working, and the printf log is: Fig 12 The board displays the result like this: Fig 13 At this point, the app with SDRAM has been successfully run in combination with SBL, indicating that the configuration of SBL with SDRAM is successful.        
View full article
RT1170 Boundary Scan test based on lauterbach   1. Abstract Boundary Scan is a method of testing interconnections on circuit boards or internal sub-blocks of circuits. You can also debug and observe the pin status of the integrated circuit, measure the voltage or analyze the sub-modules inside the integrated circuit, and test based on the JTAG interface. NXP officials have provided two good application notes: AN13507 (LPC) and AN12919 (RT). Based on the reference application note test method, this article provides the boundary scan test results for NXP MIMXRT1170-EVK revC1. It can use Lauterbach to connect the chip and perform boundary scan to control the external pins. A script file is also provided. It can realize one-click connection to boundary scan and achieve level control of external pins. 2. RT1170 test details   2.1 Hardware platform Lauterbach:LA3050 MIMXRT1170-EVK rev C1: The hardware modification point is to remove the onboard resistors R187, R208, R195 and R78. The purpose is that J6 prohibits external circuits from interfering with JTAG related pins. Disconnect J5, J6, J7, J8, that is, disconnect the onboard debugger, and use an external Lauterbach connection to J1. The connection situation is as follows: Fig 1 RT1170 directly supports both SWD and JTAG by default, so unlike RT10XX which needs to modify the fuse to convert from SWD to JTAG, RT1170 can directly use the JTAG interface.   2.2 Software operation Download Lauderbach's supporting software and install it. After installation, open the TRACE32 ICD Arm USB. If the Lauderbach device is connected, the interface will open successfully. Fig 2 At this time, you can enter the relevant commands in the yellow box in the picture above. Here you need to prepare the .bsdl file of the chip, which is usually placed on the chip introduction page of nxp.com. For example, the link to the bsdl file of RT1170 is: https://www.nxp.com/downloads/en/bsdl/i.MXRT1170_BDSL.bsdl You can copy the i.MXRT1170_BSDL.bsdl file to the Lauderbach installation path: C:\T32 Next, enter the following command in the window to open the boundary scan window and the i.MXRT1170_BSDL.bsdl file: SYStem.Mode Down BSDL.RESet BSDL.ParkState Select-DR-Scan BSDL.state Here, it will open the window: Fig 3 Click FILE item, input the downloaded i.MXRT1170_BSDL.bsdl, then in the window.,input the commander: BSDL.SOFTRESET Fig 4 Click check->BYPASSall,IDCODEall,SAMPLEall, make sure the 3 methods can be passed. Fig 5 Fig 6 Fig 7 To test the output control situation, it need to do the following operation: BSDLSET 1.: instructions->EXTEXT, DR mode->Set Write, Fileter data->uncheck intern BSDL.state->Run: check SetAndRun, TwoStepDR, Click RUN. BSDLSET 1. Can control the related pins, eg, GPIO_AD_26 is on the on board D34 LED. 1 ON,0 OFF. Fig 8   2.3 Automation control command script As can be seen from Section 2.2, single-step operation requires manual typing of commands. In actual testing, the efficiency is very low, so scripting language can be used to directly implement automated command control. Below, taking RT1170 as an example, we provide a script to control the on-board D34 light on and off. In this way, when the TRACE32 software is opened, you only need to open the script directly, enter the debug mode, run it to the end with one click, and check the on-board light control status. Script language file, the suffix is .cmm, step: File->New Script, enter the following script command: ;system setup SYStem.Mode Down SYStem.CPU CortexM7 SYSTEM.CONFIG.DEBUGPORTTYPE JTAG SYStem.JtagClock 1MHz ;BSDL Settings BSDL.RESet BSDL.ParkState Select-DR-Scan BSDL.state ;configure boundary scan chain BSDL.FILE i.MXRT1170_BDSL.bsdl ;Check boundary scan chain BSDL.SOFTRESET BSDL.BYPASSall BSDL.IDCODEall BSDL.SAMPLEall ;Perform Sample test BSDL.RUN BSDL.SetAndRun ON BSDL.TwoStepDR ON BSDL.SET 1. BSDL.SET 1. IR EXTEST BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s Function, the led will be blinking 5 times, duration is 1s. Save the script, then debug it. Fig 9 This is the video for the testing:   It can be seen that the onboard light D34 can automatically flash, indicating that the BSDL automatic test has been completed so far.          
View full article
RT1170 flexSPI1 secondary QSPI flash debug flashdriver 1. Abstract RT1170 has two groups of flexSPI: FlexSPI1, FlexSPI2. Each group of flexSPI is also divided into primary option group and secondary pin group. For specific chip connections, please refer to the following article: https://www.cnblogs.com/henjay724/p/15139381.html NXP provided burning algorithms are started from the flexSPI1 primary group for RT1170. However, in actual use, some customers need to start from the flash of the FlexSPI1 secondary pin group and use the debugger to program the chip. How to prepare the corresponding flash algorithm? Moreover, different debuggers correspond to different program algorithms. This article will take RT1170 flexSPI1 secondary pin group flash boot as an example to explain how to use CMSIS DAP and JLINK as debugger to prepare the corresponding burning algorithm and do debug, as well as the necessary conditions for booting from the secondary port, and provide modified flash algorithm which can be directly used to debug and programming. Here, I would like to thank the customer who are providing the test platform, because the official MIMXRT1170-EVK is an external QSPI flash connected from the FlexSPI1 primary interface and does not provide a secondary group interface. 2 Related prepare To test the FlexSPI1 Secondary pin group, you must first prepare a board that connects the QSPI flash to the Secondary pin, and then configure the FlexSPI_PIN_GROUP_SEL fuse to 1. Since the FlexSPI1 secondary pin group is already connected to the GPIO_AD port, the maximum speed limit is 104Mhz.    Fig 1 2.1 Hardware prepare Fig 2 2.2 fuse FLEXSPI_PIN_GROUP_SEL burn   FLEXSPI_PIN_GROUP_SEL fuse address is 0X9A0[10]: Fig 3 To burn fuse, let the chip to enter serial download mode and connect through MCUBootutility. When connecting, you need to select the FlexSPI1 secondary option, as follows:   Fig 4 Burn fuse result is:   Fig 5 After the fuse is burned successfully, change the board boot mode to internal boot mode, then we can program the app and boot from the flash which is connecting to the FlexSPI1 secondary pin group. 3 Flash algorithm modification and debug test Regarding the flash algorithm of RT1170 FlexSPI1 for secondary pin group, this article mainly focuses on the preparation and testing of MCUxpresso IDE, two debuggers: CMSIS DAP's .cfx, and JLINK's RT-UFL flash algorithm. Here is a brief explanation of the principle of modifying the flash algorithm. It is actually based on the ROM API. Therefore, the main modification point is : option0 =0xc1000005, option1=0x00010000.   Fig 6 3.1 CMSIS DAP .cfx flash algorithm prepare and test The algorithm source code of RT1170 CMSIS DAP can be found in the path of MCUXpressoIDE: C:\nxp\MCUXpressoIDE_11.8.0_1165\ide\Examples\Flashdrivers\NXP\iMXRT\iMXRT117x_FlexSPI_SFDP.zip After importing the algorithm source code, first compile the LPCXFlashDriverLib<Release_SectorHashing> version to get the lib that needs to be called. For iMXRTt117x_FlexSPI_SFDP, select the MIMXRT1170_SFDP_QSPI (FlexSPI1 Port A QSPI) version, and modify Imxrt117xFlexSPI_SFDP, FlashConfig.h: #define CONFIG_OPTION0 0xc1 000005 #define CONFIG_OPTION1 0x00010000     Then compile the lib and compile Imxrt117xFlexSPI_SFDP to generate .cfx,    Fig 7 After build, the .cfx file can be found in project folder: iMXRT117x_FlexSPI_SFDP\builds Rename it: MIMXRT1170_SFDP_QSPI1_Secondary.cfx, and copy it to the IDE installation directory: C:\nxp\MCUXpressoIDE_11.8.0_1165\ide\binaries\Flash    This is done for the later app, you can directly select the corresponding .cfx in the list.    For details on how to compile the algorithm source code to obtain .cfx, you can refer to the article: https://www.cnblogs.com/henjay724/p/14190485.html    After preparing the APP and CMSIS DAP debugger, select compiled .cfx flash algorithm in the app project:   Fig 8 To the app, it should be noted that the serialClkFreq in the FCB is configured as 100MHz, and the LUT commander matches the flash command used. The FCB of W25Q128 is as follows: const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClksrc=kFlexSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock .controllerMiscOption = 0x10, .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_100MHz,//kFlexSpiSerialClk_133MHz, .sflashA1Size = 16u * 1024u * 1024u, .lookupTable = { // Read LUTs [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEC, RADDR_SDR, FLEXSPI_4PAD, 0x20), [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), // Read Status LUTs [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04), // Write Enable LUTs [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0), // Erase Sector LUTs [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x21, RADDR_SDR, FLEXSPI_1PAD, 0x20), // Erase Block LUTs [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18), // Pape Program LUTs [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x12, RADDR_SDR, FLEXSPI_1PAD, 0x20), [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), // Erase Chip LUTs [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0), }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .ipcmdSerialClkFreq = 0x1, .blockSize = 64u * 1024u, .isUniformBlockSize = false, }; Debug result is:   Fig 9 It can be seen that the modified flexSPI1 secondary group flash algorithm has been successfully called, the downloading is successful, and the app function runs normally. 3.2 JLINK RT-UFL flash algorithm prepare and test Some customers like to use JLINK, but the Segger JLINK driver algorithm source code are not open, so you can use the RT-UFL algorithm, modify it to match the option of RT1170 FlexSPI1 secondray group, and then call it.     For information on the RT-UFL algorithm, please see the following link:    https://www.cnblogs.com/henjay724/p/13951686.html https://www.cnblogs.com/henjay724/p/14942574.html https://www.cnblogs.com/henjay724/p/15430619.html    To the RT UFL modification points: ufl_main.c case kChipId_RT116x: case kChipId_RT117x: uflTargetDesc->flexspiInstance = MIMXRT117X_1st_FLEXSPI_INSTANCE; uflTargetDesc->flexspiBaseAddr = MIMXRT117X_1st_FLEXSPI_BASE; uflTargetDesc->flashBaseAddr = MIMXRT117X_1st_FLEXSPI_AMBA_BASE; uflTargetDesc->configOption.option0.U = 0xc1000005; uflTargetDesc->configOption.option1.U = 0x00010000; Build the code, generate: MIMXRT_FLEXSPI_UV5_UFL_Flexspi1secondary_qspi.FLM,copy To: C:\Program Files\SEGGER\JLINKV768B\Devices\NXP\iMXRT_UFL In file C:\Program Files\SEGGER\JLINKV768B\JLinkDevices.xml, add the new flash algorithm file calling code: <!------------------------> <Device> <ChipInfo Vendor="NXP" Name="MIMXRT1170_UFL_flexspi1_2nd" WorkRAMAddr="0x20240000" WorkRAMSize="0x00040000" Core="JLINK_CORE_CORTEX_M7" JLinkScriptFile="Devices/NXP/iMXRT_UFL/iMXRT117x_CortexM7.JLinkScript" Aliases="MIMXRT1176xxx8_M7; MIMXRT1176xxxA_M7" /> <FlashBankInfo Name="QSPI Flash" BaseAddr="0x30000000" MaxSize="0x01000000" Loader="Devices/NXP/iMXRT_UFL/MIMXRT_FLEXSPI_UV5_UFL_Flexspi1secondary_qspi.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" /> </Device> <!------------------------> In the app project, debug configuration,configure the JLINK device as: MIMXRT1170_UFL_flexspi1_2nd   Note: uncheck “reset before running”, otherwise, it will be stopped in ROM after entering the debug mode.   Fig 10 Test the debug result is:   Fig 11 We can see, when use the modified RT-UFL, the JLINK debug also works OK. 4. summarize This article mainly provides the algorithm modification of RT1170 FlexSPI1 secondary group. The algorithm modification of other Flash interfaces and port is similar. The main attention is paid to fuse and algorithm matching. This article provides two modified FlexSPI1 secondary group burning algorithms: MIMXRT1170_SFDP_QSPI1_Secondary.cfx RT-UFL modified MIMXRT_FLEXSPI_UV5_UFL_Flexspi1secondary_qspi.FLM attachments: CMSIS DAP: RT117X FlexSPI1 2nd flashalgo->CMSIS DAP->MIMXRT1170_SFDP_QSPI1_Secondary.cfx JLINK RT-UFL: RT117X FlexSPI1 2nd flashalgo\JLINK RT-UFL Copy JLINK RT-UFL folder to Segger JLINK install path: C:\Program Files\SEGGER\JLINKV768B In this way, the relevant flash algorithm can be called according to the above content.    
View full article
RT1050 FlexIO OV7670 with TFT LCDdisplay 1 Abstract Regarding the RT10XX flexIO collecting OV7670 camera data and displaying it on TFT LCD, in fact, the NXP official website has a very good application note AN12686, but the test is based on RT1010 and not EVK. It may be difficult for actual customers to test directly. When the author was supporting customers, I encountered customers who wanted to implement flexIO on RT1050 EVK to collect parallel port OV7670 data and display it on TFT LCD, which is the LCD with SPI interface, so this article gives the specific test results of the finished product, RT1050 flexIO and There are some differences between RT1010 flexIO. RT1010 flexIO has 8 shifters, but RT1050 only has 4 shifters, so some code modifications need to be made and transplanted to RT1050. Since it is going to run on MIMXRT1050-EVKB, you also need to consider the flexIO pins that can be used, modify the EVKB, and manually weld the relevant pins to configure the corresponding camera signals and LCD display signals. This article mainly comes from problems encountered by customers during testing, so it provides specific hardware connections, software code sharing, test finished product results, etc. 2. Software and hardware prepare Since AN12686 has given the principle in great detail, this article aims to give the differences and the specific conditions of working on RT1050-EVKB. 2.1 Hardware configuration The platform is based on MIMXRT1050-EVKB revA1, OV7670 module, 2.4-inch TFT LCD LCD SPI serial touch TFT color screen ILI9321, with a resolution of 240*320.     For the OV7670 module status and pin status, please check the article:    RT1050 CSI OV7670 camera eLCD display The camera module pins are as follows: Fig 1    TFT LCD picture: Fig 2 Pin No Signal Description 1 GND Power ground 2 VCC Power 3.3V 3 CLK SPI clock 4 MOSI SPI data 5 RES LCD reset 6 DC LCD data/commander select pin 7 BLK Backlight control switch, backlight is turned on by default, low level turns off the backlight 8 MISO Touch data reading 9 CS1 Display selection pin 10 CS2 Touch selection pin 11 PEN Touch interrupt signal For LCD, this article only uses the display part and does not use the rough mold part. Considering the pin layout of MIMXRT1050-EVKB, the application note flexIO1 is not used here, but FlexIO2 is selected. The actual RT1050-EVKB and OV7670 module and LCD connection pins are given below. The connection between the LCD signal pin and the MCU MIMXRT1050-EVKB RevA1 signal pin is as follows: LCD signal and pin MIMXRT1050-EVKB revA1 signal and pin GND P1 GND J24_7 3.3V VCC P2 3.3V J24_8 CLK P3 GPIO_AD_B1_15(SPI3_CLK) R98 MOSI P4 GPIO_AD_B1_14(SPI3_MOSI) R99 RES P5 GPIO_AD_B0_02(GPIO1_IO02) J24_2 DC P6 GPIO_AD_B1_10(GPIO01_IO26) J23_1 CS1 P9 GPIO_AD_B1_12(GPIO01_IO28) R100   OV7670 signal pin and MCU MIMXRT1050-EVKB RevA1 signal pin connection situation: 0V7670 signal and pin MIMXRT1050-EVKB revA1 signal and pin OV7670_D0 P3 GPIO_B0_05(FLEXIO2_D05) SW5_1 OV7670_D1 P4 GPIO_B0_06(FLEXIO2_D06) SW5.2 OV7670_D2 P5 GPIO_B0_07(FLEXIO2_D07) SW5_3 OV7670_D3 P6 GPIO_B0_08(FLEXIO2_D08) SW5_4 OV7670_D4 P7 GPIO_B0_09(FLEXIO2_D09) SW6_1 OV7670_D5 P8 GPIO_B0_10(FLEXIO2_D10) SW7_1 OV7670_D6 P9 GPIO_B0_11(FLEXIO2_D11) SW6_2 OV7670_D7 P10 GPIO_B0_12(FLEXIO2_D12) SW6_3 XCLK P11 GPIO_B0_13(FLEXIO2_D13) SW7_2 PCLK P12 GPIO_B0_14(FLEXIO2_D14) SW6_4 HREF(HS) P13 GPIO_B0_15(FLEXIO2_D15) R258/R324 VSYNC P14 GPIO_AD_B0_03(GPIO01_03) J24_1 I2C_SDA P15 GPIO_AD_B1_01(I2C1_SDA) J23_5 I2C_SCL P16 GPIO_AD_B1_00(I2C1_SCLK) J23_6 PWDN P1 GPIO_AD_B1_02(GPIO1_IO18) J22_7 RESET P2 GPIO_AD_B1_03(GPIO1_IO19) J22_8 3.3V P18 3.3V J22_7 GND P17 GND J22_8 In order to reduce the impact of the signal, MIMXRT1050-EVKB removes R323, R316, R309, and D6 on the board. The physical connection situation is as follows: Fig 3 2.2 Software configuration Since the flexIO of RT1050 is different from the 8 shifters of RT1010, the DMA configuration needs to be modified. The difference code of flexio_ov7670 is as follows:   static FLEXIO_CAMERA_Type s_FlexioCameraDevice = { .flexioBase = BOARD_CAMERA_FLEXIO_INST, .datPinStartIdx = BOARD_CAMERA_FLEXIO_DATA_PIN_START_INDEX, .pclkPinIdx = BOARD_CAMERA_FLEXIO_PCLK_PIN_INDEX, .hrefPinIdx = BOARD_CAMERA_FLEXIO_HREF_PIN_INDEX, .shifterStartIdx = 0U, .shifterCount = 4, .timerIdx = 0U, }; static void configDMA(void) { uint32_t soff, smod = 0u, size=0u; while(1u << size < DMA_TRSF_SIZE) /* size = log2(DMA_TRSF_SIZE) */ { size++; } if(DMA_TRSF_SIZE == DMA_MINOR_LOOP_SIZE) { soff = 0u; } else { soff = DMA_TRSF_SIZE; while(1u << smod < DMA_MINOR_LOOP_SIZE) /* smod = log2(DMA_MINOR_LOOP_SIZE) */ { smod++; } } /* Configure DMA TCD */ DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].SADDR = FLEXIO_CAMERA_GetRxBufferAddress(&s_FlexioCameraDevice); DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].SOFF = soff; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].ATTR = DMA_ATTR_SMOD(smod) | DMA_ATTR_SSIZE(size) | DMA_ATTR_DMOD(0u) | DMA_ATTR_DSIZE(size); DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].NBYTES_MLNO = 16; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].SLAST = 0u; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].DADDR = (uint32_t)(*pFlexioCameraFrameBuffer); DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].DOFF = 8; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].CITER_ELINKNO = DMA_MAJOR_LOOP_SIZE; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].DLAST_SGA = -OV7670_FRAME_BYTES; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].CSR = 0u; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].CSR |= DMA_CSR_DREQ_MASK; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].BITER_ELINKNO = DMA_MAJOR_LOOP_SIZE; /* Configure DMA MUX Source */ DMAMUX->CHCFG[FLEXIO_CAMERA_DMA_CHN] = DMAMUX->CHCFG[FLEXIO_CAMERA_DMA_CHN] & (~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(FLEXIO_CAMERA_DMA_MUX_SRC); /* Enable DMA channel. */ DMAMUX->CHCFG[FLEXIO_CAMERA_DMA_CHN] |= DMAMUX_CHCFG_ENBL_MASK; } The code structure adopts: the camera uses flexIO mode to collect DMA transfer. After collecting one frame, DMA stores the data into the buffer, and then displays one frame of data uniformly on the LCD. Since there are many configuration codes for flexIO OV7670 and LCD SPI, we will not explain them one by one here. Please check the attached code source code for details. There is a header file of horsepic.h in the code. This file is a 320*240 RGB565 picture of a horse. It is used to test the LCD display separately. Usually after connecting the LCD, you need to test the LCD display separately. You can use a fixed picture to get the display. , here is the method of converting the picture into a C array: First adjust the picture to the LCD resolution size, and then convert it through the LVGL online conversion tool, select CF_RGB565A8, but the RGB565 generated by this format will have 1 more byte each, you can do it yourself After deletion, it can be called by code: https://lvgl.io/tools/imageconverter Display horse picture code: convert8to16(); ILI9341_FillPic(0, 0, OV7670_FRAME_WIDTH-1u, OV7670_FRAME_HEIGHT-1u, (uint16_t *)(horse16)); Display result: Fig 4 3 Test result and summarize    About RT1050-EVKB, use flexIO to collect OV7670 data and display the situation through TFT LCD. Please check the video for the specific code situation. Check the attached source code. You can see from the video results that the flexIO OV7670 camera data can be successfully displayed and the code can successfully run the function.
View full article
  RT1050 CSI OV7670 camera eLCD display 1.Abstract OV7670 is a CMOS VGA image sensor with small size and low operating voltage. It is controlled by the SCCB bus and can output 8-bit image data of various resolutions with a frame rate of up to 30 frames/second and low cost. This article mainly implements the use of CSI on RT10XX to obtain OV7670 camera data, and displays it using the eLCDIF display module that comes with RT10XX. The camera and display use RGB565 format. The camera resolution configuration is QVGA 320*240, the LCD is NXP official EVKB matching LCD RK043FN02H, the resolution is 480*272, and the frame rate is 30FPS. This article is based on NXP official RT1050 SDK: SDK_2_14_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\csi\rgb565 Porting the OV7670 driver to implement the CSI method to collect OV7670 image data and display it on the LCD through the eLCDIF module   2. Principle explanation    Here is a brief explanation of relevant knowledge. 2.1 RGB565 Color mode As a basic color coding format for images, RGB565 refers to a pixel that occupies 2 bytes of data and is usually used in images and display devices. R red, G green, B blue, the actual display can obtain different other colors according to the configuration of the three primary colors. Each pixel bit can display 65536 (2^16) colors. The specific allocation is as follows:   Fig 1 From the above figure, we can know that the 2-byte data displayed in pure red, green and blue is: Red: 0xf800, Green: 0X07E0, Blue: 0X001F 2.2 OV7670 camera hardware and waveform situation The OV7670 module used is as follows: Fig 2 Pin situation No Signal Description 1 PWDN Power consumption selection mode, pull down for normal use 2 RET Reset port, pull high for normal use 3 D0 Data port output bit 0 4 D1 Data port output bit 1 5 D2 Data port output bit 2 6 D3 Data port output bit 3 7 D4 Data port output bit 4 8 D5 Data port output bit 5 9 D6 Data port output bit 6 10 D7 Data port output bit 7 11 XLK Clock signal input signal 12 PLK Pixel clock output signal 13 HS Horizontal synchronization signal output signal 14 VS Frame sync clock output signal 15 SDA SCCB Interface data control 16 SCL SCCB Interface clock control 17 GND GND 18 3.3V 3.3V power RGB565 output data timing: Fig 3 2.2 CSI frame synchronization signal timing waveform Fig 4 2.3 LCD display wave Fig 5 Therefore, the data of OV7670 is obtained through CSI and then stored in the buffer. The eLCDIF then retrieves the data from the buffer and displays it on the LCD screen to display the real-time collection and reality of the camera data. 3 Software and hardware realize    The test platform is based on NXP MIMXRT1050-EVKB revA1 version: https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1050-evaluation-kit:MIMXRT1050-EVK LCD为:https://www.nxp.com/part/RK043FN02H-CT#/ 3.1 Hardware connection As can be seen from Figure 2, the universal module purchased is a 2.54mm direct plug mode, but the CSI interface used on the MIMXRT1050-EVKB board is an FPC interface, so an adapter board is required to switch from FPC to 2.54mm direct plug mode. The wiring diagram is as follows:    Fig 6 The actual overall hardware connection situation is as follows: Fig 7 3.2 Software prepare Regarding the SDK driver of OV7670, the RT SDK does not provide it directly, but the FRDM-K82 SDK provides relevant drivers that can be transplanted to the RT1050 SDK.       SDK version:SDK_2_14_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\csi\rgb565 The code replaces the original OV7725 code, replaces the relevant driver with the OV7670 driver, modifies the OV7670 code, matches it to the RT1050 CSI code, and adds IO signal control for OV7670 RST and PWDN. The reason for adding RST and PWDN control is that it was found Some modules, if the RST pin is not closed and delayed to open, will cause the problem of unsuccessful acquisition. However, with the addition of RST and PWDN control, currently OV7670 from different manufacturers can successfully acquire and display stably. For the specific OV7670 code, you can view the attached source code. The camera initialization code is as follows:   static void APP_InitCamera(void) { const camera_config_t cameraConfig = { .pixelFormat = kVIDEO_PixelFormatRGB565, .bytesPerPixel = APP_BPP, .resolution = FSL_VIDEO_RESOLUTION(320, 240), /* Set the camera buffer stride according to panel, so that if * camera resoution is smaller than display, it can still be shown * correct in the screen. */ .frameBufferLinePitch_Bytes = DEMO_BUFFER_WIDTH * APP_BPP, .interface = kCAMERA_InterfaceGatedClock, .controlFlags = DEMO_CAMERA_CONTROL_FLAGS, .framePerSec = 30, }; memset(s_frameBuffer, 0, sizeof(s_frameBuffer)); BOARD_InitCameraResource(); CAMERA_RECEIVER_Init(&cameraReceiver, &cameraConfig, NULL, NULL); if (kStatus_Success != CAMERA_DEVICE_Init(&cameraDevice, &cameraConfig)) { PRINTF("Camera device initialization failed\r\n"); while (1) { ; } } CAMERA_DEVICE_Start(&cameraDevice); /* Submit the empty frame buffers to buffer queue. */ for (uint32_t i = 0; i < APP_FRAME_BUFFER_COUNT; i++) { CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t)(s_frameBuffer[i])); } } The resolution here is QVGA 320*240, which does not match the 480*272 of the LCD, but it does not matter. In fact, the size of 320*240 is displayed in the LCD. If you want to display it to 480*272, you can also configure the size through PXP. For more code details, see the attached code package. 4. Summary This article aims to provide a demo of RT OV7670 CSI+eLCDIF acquisition and display. let’s go directly to the finished product effect video. You can see that the relative display is relatively clear, and the refresh effect is also good.
View full article
LittleFS is a file system used for microcontroller internal flash and external NOR flash. Since it is more suitable for small embedded systems than traditional FAT file systems, more and more people are using it in their projects. So in addition to NOR/NAND flash type storage devices, can LittleFS be used in SD cards? It seems that it is okay too. This article will use the littlefs_shell and sdcard_fatfs demo project in the i.mxRT1050 SDK to make a new littefs_shell project for reading and writing SD cards. This experiment uses MCUXpresso IDE v11.7, and the SDK uses version 2.13. The littleFS file system has only 4 files, of which the current version shown in lfs.h is littleFS 2.5. The first step, of course, is to add SD-related code to the littlefs_shell project. The easiest way is to import another sdcard_fatfs project and copy all of the sdmmc directories into our project. Then copy sdmmc_config.c and sdmmc_config.h in the /board directory, and fsl_usdhc.c and fsl_usdhc.h in the /drivers directory. The second step is to modify the program to include SD card detection and initialization, adding a bridge from LittleFS to SD drivers. Add the following code to littlefs_shell.c. extern sd_card_t m_sdCard; status_t sdcardWaitCardInsert(void) { BOARD_SD_Config(&m_sdCard, NULL, BOARD_SDMMC_SD_HOST_IRQ_PRIORITY, NULL); /* SD host init function */ if (SD_HostInit(&m_sdCard) != kStatus_Success) { PRINTF("\r\nSD host init fail\r\n"); return kStatus_Fail; } /* wait card insert */ if (SD_PollingCardInsert(&m_sdCard, kSD_Inserted) == kStatus_Success) { PRINTF("\r\nCard inserted.\r\n"); /* power off card */ SD_SetCardPower(&m_sdCard, false); /* power on the card */ SD_SetCardPower(&m_sdCard, true); // SdMmc_Init(); } else { PRINTF("\r\nCard detect fail.\r\n"); return kStatus_Fail; } return kStatus_Success; } status_t sd_disk_initialize() { static bool isCardInitialized = false; /* demostrate the normal flow of card re-initialization. If re-initialization is not neccessary, return RES_OK directly will be fine */ if(isCardInitialized) { SD_Deinit(&m_sdCard); } if (kStatus_Success != SD_Init(&m_sdCard)) { SD_Deinit(&m_sdCard); memset(&m_sdCard, 0U, sizeof(m_sdCard)); return kStatus_Fail; } isCardInitialized = true; return kStatus_Success; } In main(), add these code if (sdcardWaitCardInsert() != kStatus_Success) { return -1; } status = sd_disk_initialize(); Next, create two new c files, lfs_sdmmc.c and lfs_sdmmc_bridge.c. The call order is littlefs->lfs_sdmmc.c->lfs_sdmmc_bridge.c->fsl_sd.c. lfs_sdmmc.c and lfs_sdmmc_bridge.c acting as intermediate layers that can connect the LITTLEFS and SD upper layer drivers. One of the things that must be noted is the mapping of addresses. The address given by littleFS is the block address + offset address. See figure below. This is a read command issued by the ‘mount’ command. The block address refers to the address of the erased sector address in SD. The read and write operation uses the smallest read-write block address (BLOCK) of SD, as described below. Therefore, in lfs_sdmmc.c, the address given by littleFS is first converted to the byte address. Then change the SD card read-write address to the BLOCK address in lfs_sdmmc_bridge.c. Since most SD cards today exceed 4GB, the byte address requires a 64-bit variable. Finally, the most important step is littleFS parameter configuration. There is a structure LittlsFS_config in peripherals.c, which contains not only the operation functions of the SD card, but also the read and write sectors and cache size. The setup of this structure is critical. If the setting is not good, it will not only affect the performance, but also cause errors in operation. Before setting it up, let's introduce some of the general ideal of SD card and littleFS. The storage unit of the SD card is BLOCK, and both reading and writing can be carried out according to BLOCK. The size of each block can be different for different cards. For standard SD cards, the length of the block command can be set with CMD16, and the block command length is fixed at 512 bytes for SDHC cards. The SD card is erased sector by sector. The size of each sector needs to be checked in the CSD register of the SD card. If the CSD register ERASE_BLK_EN = 0, Sector is the smallest erase unit, and its unit is "block". The value of sector size is equal to the value of the SECTOR_SIZE field in the CSD register plus 1. For example, if SECTOR_SIZE is 127, then the minimum erase unit is 512*(127+1)=65536 bytes. In addition, sometimes there are doubts, many of the current SD cards actually have wear functions to reduce the loss caused by frequent erasing and writing, and extend the service life. So in fact, delete operations or read and write operations are not necessarily real physical addresses. Instead, it is mapped by the SD controller. But for the user, this mapping is transparent. So don't worry about this affecting normal operation. LittleFS is a lightweight file system that has power loss recovery and dynamic wear leveling compared to FAT systems. Once mounted, littleFS provides a complete set of POSIX-like file and directory functions, so it can be operated like a common file system. LittleFS has only 4 files in total, and it basically does not need to be modified when used. Since the NOR/NAND flash to be operated by LittleFS is essentially a block device, in order to facilitate use, LittleFS is read and written in blocks, and the underlying NOR/NAND Flash interface drivers are carried out in blocks. Let's take a look at the specific content of LittleFS configuration parameters. const struct lfs_config LittleFS_config = { .context = (void*)0, .read = lfs_sdmmc_read, .prog = lfs_sdmmc_prog, .erase = lfs_sdmmc_erase, .sync = lfs_sdmmc_sync, .read_size = 512, .prog_size = 512, .block_size = 65536, .block_count = 128, .block_cycles = 100, .cache_size = 512, .lookahead_size = LITTLEFS_LOOKAHEAD_SIZE }; Among them, the first item (.context) is not used in this project, and is used in the original project to save the offset of the file system stored in Flash. Items two (.read) through five (.sync) point to the handlers for each operation. The sixth item (.read_size) is the smallest unit of read operation. This value is roughly equal to the BLOCK size of the SD card. In the SD card driver, this size has been fixed to 512. So for convenience, it is also set to 512. The seventh item (.prog_size) is the number of bytes written each time, which is 512 bytes like .read_size. The eighth item is .block_size. This can be considered to be the smallest erase block supported by the SD card when performing an erase operation. Here the default value is not important, you need to set it in the program according to the actual value after the SD card is initialized. The card used in this experiment is 64k bytes as an erase block, so 65536 is used directly here. Item 9 (.block_count) is used to indicate how many erasable blocks there are. Multiply the .block_size to get the size of the card. If the card is replaceable, it needs to be determined according to the parameters after the SD card is initialized. The tenth item (.block_cycles) is the number of erase cycles per block. Item 11 (.cache_size) is about the cache buffer. It feels like bigger is better, but actually modifies this value won't work. So still 512. Item 12 (lookahead_size), littleFS uses a lookahead buffer to manage and allocate blocks. A lookahead buffer is a fixed-size bitmap that records information about block allocations within an area. The lookahead buffer only records the information of block allocations in one area, and when you need to know the allocation of other regions, you need to scan the file system to find allocated blocks. If there are no free blocks in the lookahead buffer, you need to move the lookahead buffer to find other free blocks in the file system. The lookahead buffer position shifts one lookahead_size at a time. Use the original value here.  That’s all for the porting work. We can test the project now. You can see it works fine. The littleFS-SD project can read/write/create folder and erase. And it also support append to an exist file. But after more testing, a problem was found, if you repeatedly add->-close->-add-> close a file, the file will open more and more slowly, even taking a few seconds. This is what should be added and is not written directly in the last block of the file, but will apply for a new block, regardless of whether the previous block is full or not. See figure below. The figure above prints out all the read, write, and erase operations used in each write command. You can see that each time in the lfs_file_open there is one more read than the last write operation. In this way, after dozens or hundreds of cycles, a file will involve many blocks. It is very time-consuming to read these blocks in turn. Tests found that more than 100 read took longer than seconds. To speed things up, it is recommended to copy the contents of one file to another file after adding it dozens of times. In this way, the scattered content will be consolidated to write a small number of blocks. This can greatly speed up reading and writing.
View full article
RT10XX RT-UFL modification for QSPI QE and DQS factor 1. Abstract Recently, a customer used a QSPI flash (Puya simi P25Q16H) as XIP memory in the RT1050 project, but always encountered the phenomenon that the first time download failed, the download succeeded again after powering on again, and the app could run. To the program algorithm, they use the RT-UFL. After analysis, this situation is usually related to the fact that the QE of the new QSPI flash is not enabled. Therefore, based on the QE position of the QSPI flash used by the customer, the author specially enabled the corresponding QE in the SDK flexspi_nor_polling_transfer code, let the customer try to run it in RAM to check whether still have the program issues after enabling QE in the new QSPI flash. However, the customer even can’t run flexspi_nor_polling_transfer project. According to the customer's previous description, the hardware can run RAM code, and the first flash download does not work, but it can run after re-downloading, so the hardware works. Based on the phenomenon, it is initially speculated that the new problem may be related to FlexSPI DQS being occupied. Under normal circumstances, it is recommended to leave FlexSPI DQS floating. Because the project flexSPI frequency given to customers is 120Mhz, if DQS is used, the internal sampling clock source of FlexSPI read data is: Read strobe provided by memory device and input from DQS pad. This method will have problems. So asked the customer to confirm the hardware again. The result is DQS is used as a control pin for other circuits on the customer's board. Usually there are two points to note in this situation: First, the FlexSPI clock is controlled within 60MHz. Second, the internal sampling clock source configuration of FlexSPI read data is: Dummy read strobe generated by FlexSPI controller and looped back internally (FlexSPIn_MCR0[RXCLKSRC] = 0x0)      Therefore, this article focuses on how to prepare the test code for the corresponding QE position based on the QSPI flash used by the customer, consider the operation when DQS is enabled, modify and test the RT-UFL downloading algorithm. 2. Hardware and software prepare To reproduce the customer issues, need to prepare the related software, hardware, and the flash programming flashdriver, and the code for testing the QE situation. 2.1 Hardware prepare MIMXRT1050-EVKB, modify the on board resistor, from the default hyperflash to QSPI flash. The modification points: USE QSPI FLASH(Mount R153~R158, DNP R356,R361~R366)。 Remove the on board U33 ISSI QSPI flash, burn the new QSPI flash with customer used Puya simi P25Q16H. Customer is using JLINK, so prepare JLINK plus for downloading. 2.2 flexspi_nor_polling_transfer software prepare SDK2.14.0 code:flexspi_nor_polling_transfer, used to test the QE situation. App project: led_blinky RT-UFL program algorithm code: https://github.com/JayHeng/RT-UFL JLINK driver: used JLINKV768B, higher version is also OK. 2.2.1 P25Q16H QE position Fig 1    We can see, it is still the typical Status register bit 9. The related LUT write and read commander is: Fig 2 We can see that for writing, it is command 0X01, and 2 consecutive bytes need to be written. But for the read command, the commands for the two status register bytes are separate. So you need to pay attention to this when operating the QE bit. 2.2.2 flexspi_nor_polling_transfer code prepare This code is mainly used to test the QE enablement and disabling, and the erase, write and read functions of external flash. The code modification points include: modifying the LUT command to comply with P25Q16H; adding QE read, write and erase functions; modifying the frequency of flexSPI and the situation of DQS loopback internal. The relevant code is as follows: LUT related commander: flexspi_nor_polling_transfer.c const uint32_t customLUT[CUSTOM_LUT_LENGTH] = { /* Normal read mode -SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Fast read mode - SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Fast read quad mode - SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04), /* Read extend parameters */ [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Write Enable */ [4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Erase Sector */ [4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),//0xD7 /* Page Program - single mode */ [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Page Program - quad mode */ [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Read ID */ [4 * NOR_CMD_LUT_SEQ_IDX_READID] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Enable Quad mode */ [4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04), /* Enter QPI mode */ [4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Exit QPI mode */ [4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Read status register */ [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Read status register */ [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Erase whole chip */ [4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),//0xC7 }; flexspi_nor_flash_ops.c: QE read and write status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; status_t status; uint32_t writeValue = FLASH_QUAD_ENABLE; #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_cache_status_t cacheStatus; flexspi_nor_disable_cache(&cacheStatus); #endif /* Write enable */ status = flexspi_nor_write_enable(base, 0); if (status != kStatus_Success) { return status; } /* Enable quad mode. */ flashXfer.deviceAddress = 0; flashXfer.port = FLASH_PORT; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG; flashXfer.data = &writeValue; flashXfer.dataSize = writeValue <= 0xFFU ? 1 : 2; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } status = flexspi_nor_wait_bus_busy(base); /* Do software reset. */ FLEXSPI_SoftwareReset(base); #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_nor_enable_cache(cacheStatus); #endif return status; } status_t flexspi_nor_disable_quad_mode(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; status_t status; uint32_t writeValue = 0x0;//FLASH_QUAD_ENABLE; #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_cache_status_t cacheStatus; flexspi_nor_disable_cache(&cacheStatus); #endif /* Write enable */ status = flexspi_nor_write_enable(base, 0); if (status != kStatus_Success) { return status; } /* Enable quad mode. */ flashXfer.deviceAddress = 0; flashXfer.port = FLASH_PORT; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG; flashXfer.data = &writeValue; flashXfer.dataSize = 2; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } status = flexspi_nor_wait_bus_busy(base); /* Do software reset. */ FLEXSPI_SoftwareReset(base); #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_nor_enable_cache(cacheStatus); #endif return status; } status_t flexspi_nor_QE_register(FLEXSPI_Type *base, uint32_t *QEvalue) { /* Wait status ready. */ bool isBusy; uint32_t readValue; status_t status; flexspi_transfer_t flashXfer; flashXfer.deviceAddress = 0; flashXfer.port = FLASH_PORT; flashXfer.cmdType = kFLEXSPI_Read; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1; flashXfer.data = &readValue; flashXfer.dataSize = 1; do { status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } if (FLASH_BUSY_STATUS_POL) { if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { isBusy = true; } else { isBusy = false; } } else { if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { isBusy = false; } else { isBusy = true; } } *QEvalue = readValue; } while (isBusy); return status; } QE position:App.h #define FLASH_QUAD_ENABLE 0X0200 QE operation:flexspi_nor_polling_transfer.c PRINTF("Get the QE bit value before QE enable!\r\n"); uint32_t QEvalue=0; status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue); if (status != kStatus_Success) { return status; } PRINTF("QE=%X!\r\n",(uint8_t)QEvalue); #if 1 status = flexspi_nor_disable_quad_mode(EXAMPLE_FLEXSPI); if (status != kStatus_Success) { return status; } PRINTF("Get the QE bit value after QE disable!\r\n"); status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue); if (status != kStatus_Success) { return status; } PRINTF("QE=%X!\r\n",(uint8_t)QEvalue); #endif PRINTF("Enable the QE bit value !\r\n"); /* Enter quad mode. */ status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI); if (status != kStatus_Success) { return status; } status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue); if (status != kStatus_Success) { return status; } PRINTF("QE=%X!\r\n",(uint8_t)QEvalue); FlexSPI frequency modification:flexspi_nor_polling_transfer.c,app.h flexspi_device_config_t deviceconfig = { .flexspiRootClk = 60000000, .flashSize = FLASH_SIZE, .CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle, .CSInterval = 2, .CSHoldTime = 3, .CSSetupTime = 3, .dataValidTime = 0, .columnspace = 0, .enableWordAddress = 0, .AWRSeqIndex = 0, .AWRSeqNumber = 0, .ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD, .ARDSeqNumber = 1, .AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle, .AHBWriteWaitInterval = 0, }; static inline void flexspi_clock_init(void) { const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll); CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 5); /* flexspi clock 60M. */ } Loop back internally:app.h #define EXAMPLE_FLEXSPI_RX_SAMPLE_CLOCK kFLEXSPI_ReadSampleClkLoopbackInternally 2.2.3 flexspi_nor_polling_transfer testing after modification Download the modified code to RT1050 RAM and run the results as follows:    Fig 3 From the figure, we can see, QE can normally implement the functions of reading, writing, erasing, and reading. It is read as 2 here which QE is enabled for the first time, because the QSPI in this article has been operated previously. If it is a new chip, it will read 0 by default, which means that QE is not enabled. And it can be seen that after modification, it can accurately erase, program, and read external flash, indicating that the current code modification is successful. LUT, QE position, DQS consideration (60Mhz+loopback internal) are all working. 2.3 APP prepare Use the led_blinky code in the SDK to mainly modify the frequency of FCB and readSampleClkSrc. evkbimxrt1050_flexspi_nor_config.c is modified as follows:    const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally, .csHoldTime = 3u, .csSetupTime = 3u, .controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable), .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_60MHz, .sflashA1Size = 8u * 1024u * 1024u, … }   This code will be used to test the new modified program flashdriver in debug mode, compile the project, generate the .srec, used for the JFLASH method flash program.   3. RT-UFL JLINK flash algorithm modification After downloading the super download algorithm RT-UFL, you need to modify the super download algorithm based on the two factors mentioned above: First, QE is enabled; second, DQS is used. For the solution in this article, RT-UFL still uses option ROM to initialize flexSPI. According to the options description, choose: OPTION 0: 0xc0000201 OPTION 1:0x0 Just like this situation: Fig 4 3.1 RT-UFL code modification Here, use the keil project: \RT-UFL-1.0\build\mdk The code modification is as follows: Ufl_main.c: ufl_set_target_property1 case kChipId_RT105x: uflTargetDesc->flexspiInstance = MIMXRT105X_1st_FLEXSPI_INSTANCE; uflTargetDesc->flexspiBaseAddr = MIMXRT105X_1st_FLEXSPI_BASE; uflTargetDesc->flashBaseAddr = MIMXRT105X_1st_FLEXSPI_AMBA_BASE; //p25q16h QESet bit 1 in Status Register 2 {.option0.U = 0xc0000201, .option1.U = 0x00000000}, uflTargetDesc->configOption.option0.U = 0xc0000201; uflTargetDesc->configOption.option1.U = 0x0; Ufl_romapi.c: readSampleClkSrc configuration status_t flexspi_nor_auto_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option) { // Wait until the FLEXSPI is idle register uint32_t delaycnt = 10000u; while(delaycnt--) { } status_t status = flexspi_nor_get_config(instance, config, option); if (status != kStatus_Success) { return status; } config->memConfig.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally; //For DQS is used by other circuit return flexspi_nor_flash_init(instance, config); } FlashDev.c struct FlashDevice const FlashDevice = { FLASH_DRV_VERS, // Driver Version, do not modify! "MIMXRT_FLEXSPI", // Device Name EXTSPI, // Device Type 0x60000000, // Device Start Address 0x00800000, // Device Size in Bytes (8mB) 256, // Programming Page Size 0, // Reserved, must be 0 0xFF, // Initial Content of Erased Memory 100, // Program Page Timeout 100 mSec 5000, // Erase Sector Timeout 5000 mSec // Specify Size and Address of Sectors 0x1000, 0x00000000, // Sector Size 4kB (256 Sectors) SECTOR_END }; FlashOS.h: it will generate the UFL_L0 type, to define the flash page, sector size #define FLASH_DRV_SIZE_OPT (0) #if (FLASH_DRV_SIZE_OPT == 0) #define FLASH_DRV_PAGE_SIZE (0x100) #define FLASH_DRV_SECTOR_SIZE (0x1000) #elif (FLASH_DRV_SIZE_OPT == 1) #define FLASH_DRV_PAGE_SIZE (0x200) #define FLASH_DRV_SECTOR_SIZE (0x1000) #elif (FLASH_DRV_SIZE_OPT == 2) #define FLASH_DRV_PAGE_SIZE (0x200) #define FLASH_DRV_SECTOR_SIZE (0x10000) #endif Compile the code, it will get flashdriver firmware:MIMXRT_FLEXSPI_UV5_UFL.FLM Rename it to:MIMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM 3.2 JLINK driver flashdriver update After installing the JLINK driver,  modify it to use the RT-UFL algorithm.   According to this article, the driving algorithm of JLINK is modified to RT-UFL algorithm: https://www.cnblogs.com/henjay724/p/14942574.html   In fact, just copy: RT-UFL-1.0\RT-UFL-1.0\algo\SEGGER\JLink_Vxxx To the installed JLINK path: C:\Program Files\SEGGER\JLINKV768B   But this article need to based on this to add the modified flash algorithm for P25Q16H, the modification points are: (1)Copy attached file RT1050_P25Q16H_JLINK\program\ JLinkDevices.xml to: C:\Program Files\SEGGER\JLINKV768B Fig 5 The .xml modification is as follows, add the P25Q16H item and it’s algorithm: Fig 6 Note: device name is MIMXRT1050_UFL_P25Q16H (2) CopyRT1050_P25Q16H_JLINK\program\ IMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM to:C:\Program Files\SEGGER\JLINKV768B\Devices\NXP\iMXRT_UFL Fig 7 This MIMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM is the modified flashdriver algorithm in the above. (3)run C:\Program Files\SEGGER\JLINKV768B\JLinkDLLUpdater.exe, update the modified driver to the IDE IAR 3.3 Flashdriver algorithm downloading test For MIMXRT1050-EVKB, to use external JLINK, you need to disconnect J33 on the EVKB board and plug JTAG into J21. 3.3.1 Use JFLASH downloading test First, use the previously modified EVKB-IMXRT1050-flexspi_nor_polling_transfer, disable the QE bit, to simulate the new QSPI flash chip. The test is as follows:   Fig 8 JFlash test result is: Fig 9 We can see, use the Jflash with new flashdriver, can program the flash successfully. 3.3.2 led_blinky app debug test Disable the QE bit, to simulate the new QSPI flash chip, the test as Fig 8. APP demo use the IAR project(customer use it), option select JLINK: Fig 10 Fig 11 It should be noted here that the device is selected as the modified super download algorithm device name. The method is as follows. The settings->xxx.jlink generated by IAR debug is modified as follows: Fig 12 Two points: override =1, and device is the new modified algorithm device name. Debug test result: Fig 13 We can see that the algorithm can be successfully debugged and the algorithm is also modified by UFL. Run it at full speed and you can see the on board LED is flashing. It means that all flash driver algorithms, hardware, and codes already support the new P25Q16H QSPI flash. 4. Summary When using a new QSPI flash, first need to pay attention to the position of QE and whether DQS is used, and then prepare the corresponding RT-UFL programming algorithm. The UFL algorithm can usually support most flash chips by default. When QE and DQS are used, they only need to fine-tune the algorithm to support the new QSPI flash. Therefore, this article has successfully solved the problem of burning customer projects after modifying the algorithm. For other QSPI flash, you can also use the method in this article to modify the burning algorithm accordingly to ensure that it meets your own project needs.  
View full article
RT1170 AVB fresh tasting 1 Abstract AVB (Audio Video Bridging) is the audio and video bridging technology. AVB is also a time-sensitive network. It is mainly used to solve audio and video transmission problems within the local area network: delay problems and synchronization problems. AVB consists of a series of IEEE standards aimed at efficiently transmitting audio and video data in a local area network. The protocol of AVB is as follows: Fig 1 AVB is mainly a link layer protocol and coexists with the traditional TCP/IP protocol.     AVB related protocols include: gPTP (IEEE 802.1AS-2020): Precision time synchronization protocol AVTP (IEEE 1722-2016): Audio and video transmission protocol FQTSS (IEEE 802.1Q-2018, section 34): Credit Based Shaper protocol SRP (IEEE 802.1Q-2018, section 35) :Stream Reservation Protocol AVDECC (IEEE 1722.1-2013): Audio and video management protocol EST (IEEE 802.1Qbv-2015) FP (IEEE 802.3br-2016/IEEE 802.1Qbu-2016) The topology diagram of AVB is as follows: Fig 2 End Station:Listener andTalker Listener: Node that accepts audio and video data Talker: Node that outputs audio and video data AV Bridge:AVB bridge The purpose of this article is not to talk about the AVB protocol. As a first-time experience of AVB with RT1170, it mainly explains how to use the officially provided AVB/TSN protocol stack to implement the AVB audio data transmission function on the NXP MIMXRT1170-EVK board.。 2 .RT1170 AVB testing 2.1 Hardware prepare    2*MIMXRT1170-EVK REV C4,one is Talker,another is Listener.    Pin modification: remove R228, R234, R232, R229 resistor    Board default configuration:      J27:1-2      J5,J6,J7,J8:short connect      J38:5-6      SW1: 1-OFF,2-OFF,3-ON,4-OFF      SW2: 1-OFF,2-OFF,3-OFF,4-OFF,5-OFF,6-OFF,7-OFF,8-OFF,9-OFF,10-OFF      J11: code downloading and vcom port      J4  : 1G ENET, used for AVB communication Fig 3   2.2 Software tool prepare 2.2.1 Related code SDK_2_13_0_MIMXRT1170-EVK: https://mcuxpresso.nxp.com/en/builder?hw=MIMXRT1170-EVK&rel=667 Download the corresponding SDK according to the system which you need to use (windows/linux). For example, download the Linux version for Linux, and download the windows version for windows. This article takes the Linux compilation system as an example, so download the SDK Linux version. genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0.zip: https://mcuxpresso.nxp.com/en/dashboard?download=84124a72b3f5916f99168a06ef287f2f genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0 file includes: Fig 4 Binaries:include RT1170 AVB/TSN bin file, RT1050 AVB bin file. Doc:AVB/TSN stack related document, very important, recommend to read it at first. Genavb-apps-freertos-5_6_0:GenAVB/TSN app examples genavb-sdk –5_6_0.tar.gz GenAVB/TSN SDK supported configuration and device .patch:GenAVB/TSN patch to RT1170,RT1050 SDK   2.2.2 Related software tool Linux platform CMake (>= 3.10.2, tested with 3.16.3) make unzip patch Windows platform CMake (>= 3.10, tested with 3.22.1) minGW-w64 (tested with 4.3.5) 7zip Git with git bash (necessary for patch utility) This document use the linux ubuntu platform, the software version is: Fig 5 A small experience sharing, as the used Ubuntu version is lower, then the installed cmake version is also low, when install the cmake 3.16.3, meet some issues, here share the experience: At first, download cmake-3.16.3-Linux-x86_64.tar.gz: https://github.com/Kitware/CMake/releases/download/v3.16.3/cmake-3.16.3-Linux-x86_64.tar.gz unzip cmake-3.16.3-Linux-x86_64.tar.gz to get cmake-3.16.3-Linux-x86_64: tar -zxvf cmake-3.16.3-Linux-x86_64.tar.gz Add the linker to /usr/bin/cmake: sudo ln -s /home/nxa07323/TSN_GENAVB/cmake-3.16.3-Linux-x86_64/bin/cmake /usr/bin/cmake In /usr/bin/cmake path, use:ls -al, we can see the link information: Fig 6 After the above operation, use : cmake –version We can see the cmake version is cmake 3.16.3, which Fig 5 shows. 2.2.2 Code configuration   To build the AVB code, it also needs to use the RT1170 SDK, the steps are:   Unzip genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0.zip and SDK_2_13_0_MIMXRT1170-EVK_linux.zip Fig 7   Enter SDK_2_13_0_MIMXRT1170-EVK_linux folder path, add genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/ mcuxpresso-sdk-SDK_2_13_0_MIMXRT1170-EVK-5_6_0.patch  Patch add commander is: $ patch -p1 < path/to/mcuxpresso-sdk-SDK_2_13_0_MIMXRT1170-EVK-5_6_0.patch   The real operation command is: patch -p1 < /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/mcuxpresso-sdk-SDK_2_13_0_MIMXRT1170-EVK-5_6_0.patch Fig 8    Add the linker for the SDK and AVB SDK, the structure is: genavb-apps-freertos-5_6_0 ├── boards │ ├── evkbimxrt1050 │ │ ├── demo_apps │ │ └── mcu-sdk -> /path/to/SDK_2_13_0_EVKB-IMXRT1050 (required for RT1052) │ ├── evkmimxrt1170 │ │ ├── demo_apps │ │ └── mcu-sdk -> /path/to/SDK_2_13_0_MIMXRT1170-EVK (required for RT1176) │ └── src │ └── demo_apps └── gen_avb -> /path/to/genavb-sdk-5_6_0 To the RT1170, it contains 2 link: 1)Add the SDK path for the avb sdk board level $ cd path/to/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170 $ ln -s path/to/SDK_2_13_0_MIMXRT1170-EVK mcu-sdk The used situation: For path /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170 It needs to add the SDK path link: /home/nxa07323/avbdoc/SDK_2_13_0_MIMXRT1170-EVK_linux Firstly, unzip the genavb-apps-freertos-5_6_0.tar.gz: tar -zxvf genavb-apps-freertos-5_6_0.tar.gz Fig 9 The commander is: cd /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170 ln -s /home/nxa07323/avbdoc/SDK_2_13_0_MIMXRT1170-EVK_linux mcu-sdk Fig 10   We can see, in the path genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170, already add the SDK path with link, the name is: mcu-sdk. 2)Add the GENAVB/TSN SDK path link to AVB app top level $ cd path/to/genavb-apps-freertos-5_6_0/ $ ln -s path/to/genavb-sdk-5_6_0 gen_avb To /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/ Add the AVB SDK path link:/home/nxa07323/avbdoc/SDK_2_13_0_MIMXRT1170-EVK_linux Unzip genavb-sdk-5_6_0.tar.gz: tar -zxvf genavb-sdk-5_6_0.tar.gz Fig 11 Link commander: cd /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0 ln -s /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-sdk-5_6_0 gen_avb Fig 12 We can see, /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0 path link also added, the name is gen_avb. 2.3 code build   The build file path: genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170/demo_apps/avb_tsn/avb_audio_app/armgcc use build_release.sh file for the linux version. Commander: ./build_release.sh Fig 13 Result: Fig 14 We can see, the avb_app.bin already be generated. File path: /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170/demo_apps/avb_tsn/avb_audio_app/armgcc/release Open avb_app.bin file: Fig 15     We can see, the generated bin file’s RT1170 QSPI FCB. 2.4 Code programming 2.4.1 MSD downloading method     By referring the doc: genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0\doc\NXP_GenAVB_TSN_Stack_FreeRTOS_Eval_User_s_Guide-5_6_rev0.pdf, It is recommended to use the MSD method and directly copy app_avb.bin to the MSD of EVK. However, in the actual test, since there is no information for successful burning progress after copying, it is easy to cause problems. For example, after copying the bin file to the MSD disk (it seems that the copy has been completed), reset or power off the board, but the burning has not actually been completed. At this time, there will be a problem that the code has not been successfully burned, and AVB cannot be successfully run. Therefore, if you use the MSD method, after copying to the MSD, it is best to wait for a period of time to ensure that the code is successfully burned, such as 30s. Fig 16 However, after many tests, the MSD method cannot perform chip mass erase. For example, some filesystem configurations of AVB have been made, but the code needs to be re-downloaded for reconfiguration. It is found that even if app_avb.bin is burned again, the previous AVB configuration is still exists, so if you need a new system file configuration, it is recommended to perform a full chip erase first and then use this method to burn, or directly use the serial download mode to burn.     In addition, some customers may update EVK's opensda version, and sometimes the updated opensda may not have MSD. In this way, it is also recommended to use the following serial download MCUBootutility method to burn.    2.4.2 MCUBootutility downloading method At first, EVK enter the serial download mode: SW1:1-OFF,2-OFF,3-OFF,4-ON Use two USB cable to connect the J11 and J20 SDP, then power off and power on the board or reset the board to enter the serial download mode. MCUBootutility tool download link: https://github.com/JayHeng/NXP-MCUBootUtility/releases/tag/v5.3.0 Tool related document: https://github.com/JayHeng/NXP-MCUBootUtility   Use the generated avb_app.bin file, and burn it to the MIMXRT1170-EVK board: Fig 17 It should be noted here that from Figure 15 you can see that the bin file stores the FCB starting from 0, but for the MIMXRT1170 chip, the FCB storage is offset by 0X400, so the burning position of avb_app.bin needs to start from 0X30000400. Follow the 7-steps in Figure 17 to burn the bin file. After burning in this way, change SW1 of EVK to: 1-OFF, 2-OFF, 3-ON, 4-OFF, which is the internal boot mode.   AVB testing requires two MIMXRT1170-EVK development boards. The codes burned on the two boards are the same, avb_app.bin is burned in both.   After restarting and testing, you will find that the old filesystem has also been cleared. At this time, you can configure a new system file again.     2.5 talker listener configuration   Two MIMXRT1170-EVK board, one as AVB Talker, another as AVB Listener. Because the programmed app is the same, then just need to use the filesystem to configure which EVK is talker, which is listener.   This document use 2 EVK, and with the back-to-back method, the connection is: Fig 18 Talker: collect the Mic audio data, then transfer to the Listener through the AVB network Listener:receive the talker audio data, play the talker mic audio data through Audio Out J33 2.5.1 Talker filesystem configuration Talker related configuration commander is: ---------------------------------------- cd .. ls mkdir avb_app write avb_app/mclock_role 0 mkdir avdecc write avdecc/btb_mode 0 mkdir fgptp write fgptp/gmCapable 1 mkdir port0 write port0/hw_addr 00:22:33:44:55:66 ----------------------------------------------- The description for the talker configuration: avb_app/mclock_role=0, Media Clock Master. avdecc/btb_mode=0, avdecc back-to-back mode fgptp/gmCapable=1,gPTP grand master port0/hw_addr=00:22:33:44:55:66, configure the hardware address For hw_addr, it should be noted that the first byte must be 00. The author previously configured it as 11, but the communication was always unsuccessful. Through EVK's J11 serial port configuration, after powering on, you can see that the terminal prints a lot of data. First, you need to enter the shell and press the ISERT key. At this time, the terminal will appear >>. For specific shell commands, you can view the documentation: NXP_GenAVB_TSN_Stack_FreeRTOS_Eval_User_s_Guide-5_6_rev0.pdf, Chapter 6.1.1 Filesystem commands The mainly used commander is: write: write a file with a given string cat: print the content of a file ls: list all files and directories in the current directory rm: remove a file or a directory (if it is empty) cd: change directory pwd: print working directory mkdir: create a directory The following picture is for the shell entry and the file system configuration: Fig 19  According to the Talker command mentioned above, configure the talker file system: Fig 20   Until now, the talker filesystem is configured. 2.5.2 Listener filesystem configuration   Listener related commander is: ------------------------------- cd .. ls mkdir avb_app write avb_app/mclock_role 1 mkdir avdecc write avdecc/btb_mode 1 write avdecc/talker_id 0x00049f4455660000 ------------------------------------------ The description for the listener configuration: avb_app/mclock_role =1, Media Clock Slave. avdecc/btb_mode=1, avdecc fast-connect back-to-back mode avdecc/talker_id =0x00049f4455660000,for fast connect mode configure the talker entity id。 Entity id configuration rule is: eui[0] = 0x00; eui[1] = 0x04; eui[2] = 0x9f; eui[3] = mac_addr[3]; eui[4] = mac_addr[4]; eui[5] = mac_addr[5]; eui[6] = 0x00; eui[7] = 0x00; mac_addr is determined by the hw_addr, eg, talker configure the hw_addr to: 00:22:33:44:55:66, this is the mac_addr[0-5] Then talker_id: eui[0] = 0x00; eui[1] = 0x04; eui[2] = 0x9f; eui[3] = mac_addr[3]=44; eui[4] = mac_addr[4]=55; eui[5] = mac_addr[5]=66; eui[6] = 0x00; eui[7] = 0x00; talker_id =0x00049f4455660000。 Next, configure the Listener file system: Press the computer's insert button to enter shell mode, and then do the filesystem configuration commander input: Fig 21   Until now, the Listener filesystem configuration is finished. 2.6 Test Result Let's start the connection test. Find a network cable to connect two MIMXRT1170-EVK boards, which is the 1G network port J4 of the Talker and the listener. Listener's J33 is inserted into the earphone to listen to the microphone audio data sent from the talker board. Connection picture is as follows: Fig 22 The test result is, when two board power on, after the short time sync, the audio sound collected from the Talker microphone can be heard in the Listener's headphones, indicating that the RT1170 AVB communication is working. Partial log diagrams are given below. The complete logs of talker and listener can be viewed in the attachment. Fig 23 Fig 24 Fig 25 Fig 26 3.Summarization After several testing, we can realize the RT1170 AVB audio transfer function. If the customer don’t want to build the project, just want to do the simple testing, they also can use the AVB/TSN stack’s generated bin file, the path is: \genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0\binaries\genavb-avb_audio_app-evaluation-freertos_rt1176-5_6_0.tar\genavb-avb_audio_app-evaluation-freertos_rt1176-5_6_0\release\ avb_app.bin This document is just the AVB tasting, for the deeper knowledge, will learn and share it later. Meet issues during the testing: 1). The cmake install during the linux build, which can be found from chapter 2.2.2 Related software tool 2). The printf log is messing, in Tera Term, use the 115200 baudrate to printf, the default printf log is miss order, it is difficult to the detail content, just like this: Fig 27 Solution: Fig 28 Fig 29 After the above configuration, we can see the log is in order. 3). Board programming, at first use the MSD to download the code, but didn’t wait the 30s, then do the power off or the reset, it always causes MSD burning failure, and the generated avb_app.bin , didn’t find the FCB location is not do the 0x400 offset when use the mcubootutility, It also meet issues. So when use the mcubootutility, need to burn from 0x30000400, please refer to chapter 2.4 Code programming 4). Talker filesystem configuration for port0/hw_addr, the first bytes should be 0X00, if none 0, it will have the AVB communication issues, after modify the first byte to the 0X00 in hw_addr, the issue is solved.  
View full article
Note: for similar EVKs, see: Using J-Link with MIMXRT1170-EVKB Using J-Link with MIMXRT1060-EVKB or MIMXRT1040-EVK Using J-Link with MIMXRT1060-EVK or MIMXRT1064-EVK This article provides details using a J-Link debug probe with either of these EVKs.  There are two options: the onboard debug circuit can be updated with Segger J-Link firmware, or an external J-Link debug probe can be attached to the EVK.  Using the onboard debug circuit is helpful as no other debug probe is required.  Appnote AN13206 has more details on this, and the comparison of the firmware options for the debug circuit.  This article details the steps to use either J-Link option.   Using external J-Link debug probe Segger offers several J-Link probe options.  To use one of these probes with these EVKs, configure the EVK with these settings: Remove jumpers J6 and J7, to disconnect the SWD signals from the onboard debug circuit.  These jumpers or installed by default. Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Connect the J-Link probe to J1, 20-pin dual-row 0.1" header.   Using onboard debug circuit with J-Link firmware Disconnect any USB cables from the EVK Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Short jumper J22 to force the debug circuit in DFU mode Connect a USB cable to J11, to the on-board debugger Follow Appnote AN13206 to program the J-Link firmware to the EVK Unplug the USB cable at J11 Remove the jumper at J22 Plug the USB cable back in to J11.  Now the on-board debugger should boot as a JLink. Install jumpers J6 and J7, to connect the SWD signals from onboard debug circuit.  These jumpers or installed by default. Note: with the JLink firmware loaded, USB J11 is no longer an option to power the EVK.  Another option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  For this power option, jumper J38 needs to short 1-2, which is the default setting. 
View full article
Note: for similar EVKs, see: Using J-Link with MIMXRT1060-EVKB or MIMXRT1040-EVK Using J-Link with MIMXRT1170-EVKB Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK This article provides details using a J-Link debug probe with either of these EVKs.  There are two options: the onboard debug circuit can be updated with Segger J-Link firmware, or an external J-Link debug probe can be attached to the EVK.  Using the onboard debug circuit is helpful as no other debug probe is required.  However, the onboard debug circuit will no longer power the EVK when updated with the J-Link firmware.  Appnote AN13206 has more details on this, and the comparison of the firmware options for the debug circuit.  This article details the steps to use either J-Link option.   Using external J-Link debug probe Segger offers several J-Link probe options.  To use one of these probes with these EVKs, configure the EVK with these settings: Remove jumpers J47 and J48, to disconnect the SWD signals from onboard debug circuit.  These jumpers or installed by default. Use default power selection on J1 with pins 5-6 shorted. Connect the J-Link probe to J21, 20-pin dual-row 0.1" header. Power the EVK with one of the power supply options.  Typically USB connector J41 is used to power the board, and provides a UART/USB bridge through the onboard debug circuit.   Using onboard debug circuit with J-Link firmware Follow Appnote AN13206 to program the J-Link firmware to the EVK Install jumpers J47 and J48, to connect the SWD signals from onboard debug circuit.  These jumpers or installed by default. Plug USB cable to J41.  This provides connection for J-Link debugger and UART/USB bridge.  However, with J-Link firmware, J41 no longer powers the EVK Power the EVK with another source.  Here we will use another USB port.  Move the jumper on J1 to short pins 3-4 (default shorts pins 5-6) Connect a 2nd USB cable to J9 to power the EVK.  The green LED next to J1 will be lit when the EVK is properly powered.
View full article
Note: for similar EVKs, see: Using J-Link with MIMXRT1060-EVK or MIMXRT1064-EVK Using J-Link with MIMXRT1170-EVKB Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK. This article provides details using a J-Link debug probe with this EVK.  There are two options: the onboard debug circuit can be updated with Segger J-Link firmware, or an external J-Link debug probe can be attached to the EVK.  Using the onboard debug circuit is helpful as no other debug probe is required.  However, the onboard debug circuit will no longer power the EVK when updated with the J-Link firmware.  Appnote AN13206 has more details on this, and the comparison of the firmware options for the debug circuit.  This article details the steps to use either J-Link option.     Using external J-Link debug probe Segger offers several J-Link probe options.  To use one of these probes with these EVKs, configure the EVK with these settings: Remove jumpers J9 and J10, to disconnect the SWD signals from onboard debug circuit.  These jumpers or installed by default. Use default power selection on J40 with pins 5-6 shorted. Connect the J-Link probe to J2, 20-pin dual-row 0.1" header. Power the EVK with one of the power supply options.  Typically USB connector J1 is used to power the board, and provides a UART/USB bridge through the onboard debug circuit.   Using onboard debug circuit with J-Link firmware Follow Appnote AN13206 to program the J-Link firmware to the EVK. Use jumper J12 to change the mode of the onboard debug circuit: Install J12 to force bootloader mode, to update the firmware image Remove J12 to use the onboard debugger Install jumpers J9 and J10, to connect the SWD signals from onboard debug circuit.  These jumpers are installed by default. Plug USB cable to J1.  This provides connection for J-Link debugger and UART/USB bridge.  However, with J-Link firmware, J1 no longer powers the EVK Power the EVK with another source.  Here we will use another USB port.  Move the jumper on J40 to short pins 3-4 (default shorts pins 5-6) Connect a 2nd USB cable to J48 to power the EVK.  The green LED next to J40 will be lit when the EVK is properly powered.  
View full article
Note: for similar EVKs, see: Using J-Link with MIMXRT1060-EVKB or MIMXRT1040-EVK Using J-Link with MIMXRT1060-EVK or MIMXRT1064-EVK Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK This article provides details using a J-Link debug probe with this EVK.  There are two options: the onboard MCU-Link debug probe can be updated with Segger J-Link firmware, or an external J-Link debug probe can be attached to the EVK.  Using the onboard debug circuit is helpful as no other debug probe is required.  This article details the steps to use either J-Link option. MIMXRT1170-EVKB jumper locations   Using external J-Link debug probe Segger offers several J-Link probe options.  To use one of these probes with these EVKs, configure the EVK with these settings: Install a jumper on JP5, to disconnect the SWD signals from the onboard debug circuit.  This jumper is open by default. Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Connect the J-Link probe to J1, 20-pin dual-row 0.1" header.   Using onboard MCU-Link with J-Link firmware Install the MCU-Link Installer for the drivers and firmware update tool Disconnect any USB cables from the EVK Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Install a jumper at JP3 to force the MCU-Link in ISP mode Connect a USB cable to J86, to the MCU-Link debugger Go to the scripts directory in the MCU-Link software package installation and run the program_JLINK.cmd (Windows) or program_JLINK (Linux/MacOS) script by double-clicking it. Follow the onscreen instructions.  In Windows, this script is typically installed at C:\nxp\MCU-LINK_installer_3.122\scripts\program_JLINK.cmd Unplug the USB cable at J86 Remove the jumper at JP3 Plug the USB cable back in to J86.  Now the MCU-Link debugger should boot as a JLink. Remove jumper JP5, to connect the SWD signals from the MCU-Link debugger.  This jumper is open by default.  
View full article
There are two new LCD panels that are now available for i.MX RT EVKs: The original RK043FN02H-CT panel is being replaced with the newer RK043FN66HS-CTG panel, which will affect the following EVKs: i.MX RT1050 i.MX RT1060 i.MX RT1064   The original RK055HDMIPI4M panel is being replaced with the newer RK055HDMIPI4MA0 panel, which will affect the following EVKs: i.MX RT595 i.MX RT1160 i.MX RT1170   These changes are due to the previous panels being EOL by the LCD panel manufacturer. These new LCDs have the same dimensions and screen size as their original versions (4.3” 480x272 and 5.5” 720x1280 respectively) and the physical connections are the same. The version name can be found on the back of the LCD. However there are modifications to the software that may need to be made or else the LCD panel will be dark or blank when running MCUXpresso SDK demos on i.MXRT EVKs. This updated code is already available in the latest MCUXpresso SDK and SDK demos are configured by default to use the new panels.   For the i.MX RT1050/1060/1064 panel RK043FN66HS-CTG: The touch controller has changed and the SDK software has been modified to support the new touch controller. The LCD panel also has slightly different specs but the same code used for the original LCD panel will also work with the new LCD panel, so no change is necessary for display-only demos.  LCD demos are configured to support the new panel by default in the latest MCUXpresso SDK. So if you have the original panel you will need to change in the SDK code from      #define DEMO_PANEL  DEMO_PANEL_RK043FN66HS    //new panel (default SDK setting)           to       #define DEMO_PANEL  DEMO_PANEL_RK043FN02H     //older panel   For the i.MX RT595/RT1160/RT1170 panel RK055HDMIPI4MA0: Both the touch and display SDK software had to be updated to support this new panel. LCD demos are configured to support the new panel by default in the latest MCUXpresso SDK. So if you have the original panel you will need to change in the SDK code from:       #define DEMO_PANEL DEMO_PANEL_RK055MHD091    //new panel (default SDK setting)           to       #define DEMO_PANEL DEMO_PANEL_RK055AHD091    //older panel
View full article
RT1015 APP BEE encryption operation method 1 Introduction    NXP RT product BEE encryption can use the master key(the fixed OTPMK SNVS key) or the User Key method. The Master key method is the fixed key, and the user can’t modify it, in the practical usage, a lot of customers need to define their own key, in this situation, customer can use the use key method. This document will take the NXP RT1015 as an example, use the flexible user key method to realize the BEE encryption without the HAB certification.     The BEE encryption test will on the MIMXRT1015-EVK board, mainly three ways to realize it: MCUBootUtility tool , the Commander line method with MFGTool and the MCUXPresso Secure Provisioning tool to download the BEE encryption code.   2 Preparation 2.1  Tool preparation    MCUBootUtility download link:     https://github.com/JayHeng/NXP-MCUBootUtility/archive/v2.3.0.zip    image_enc2.zip download link: https://www.cnblogs.com/henjay724/p/10189602.html After unzip the image_enc2.zip, will get the image_enc.exe, put it under the MCUBootUtility tool folder: NXP-MCUBootUtility-2.3.0\tools\image_enc2\win RT1015 SDK download link: https://mcuxpresso.nxp.com/ 2.2 app file preparation    This document will use the iled_blinky MCUXpresso IDE project in the SDK_2.8.0_EVK-MIMXRT1015 as an example, to generate the app without the XIP boot header. Generate evkmimxrt1015_igpio_led_output.s19 will be used later. Fig 1 3 MCUbootUtility BEE encryption with user key   This chapter will use MCUBootUtility tool to realize the app BEE encryption with the user key, no HAB certification. 3.1 MIMXRT1015-EVK original fuse map    Before doing the BEE encryption, readout the original fuse map, it will be used to compare with the fuse map after the BEE encryption operation. Use the MCUbootUtility tool effuse operation utility page can read out all the fuse map. Fig 2 3.2 MCUbootutility BEE encryption configuration Fig 3 This document just use the BEE encryption, without the HAB certificate, so in the “Enable Certificate for HAB(BEE/OTFAD) encryption”, select: No.    Check Fig4, Select the”Key storage region” as flexible user keys, the protect region 0 start from 0X60001000, length is 0x2000, didn’t encrypt all the app region, just used to compare the original app with the BEE encrypted app code, we can find from 0X60003000, the code will be the plaintext code. But from 0X60001000 to 0X60002FFF will be the BEE encrypted code. After the configuration, Click the button”all in one action”, burn the code to the external QSPI flash. Fig 4 Fig 5 SW_GP2 region in the fuse can be burned separated, click the button”burn DEK data” is OK. Fig 6 Then read out all the fuse map again, we can find in the cfg1, BEE_KEY0_SEL is SW-GP2, it defines the BEE key is using the flexible use key method, not the fixed master key. Fig 7 Then, readout the BEE burned code from the flash with the normal burned code from the flash, and compare with it, the detail situation is: Fig 8 Fig 9 Fig 10 Fig 11 Fig 12    We can find, after the BEE encryption, 0X60001000 to 0X60002FFF is the encrypted code, 0X6000400 area add the EKIB0 data, 0X6000480 area add the EPRDB0 data. Because we just select the BEE engine 0, no BEE engine 1, then we can find 0X60000800 EKIB1 and EPRDB1 are all 0, not the valid data. From 0X60003000, we can find the app data is the plaintext data, the same result with our expected BEE configuration app encrypted range.    Until now, we already realize the MCUBootUtility tool BEE encryption. Exit the serial download mode, configure the MIMXRT10150-EVK on board SW8 as: 1-ON, 2-OFF, 3-ON, 4-OFF, reset the board, we can find the on board user LED is blinking, the BEE encrypted code is working. 4 BEE encryption with the Commander line mode    In practical usage, a lot of customers also need to use the commander line mode to realize the BEE encryption operation, and choose MFGTool download method. So this document will also give the way how to use the SDK SDK_2.8.0_EVK-MIMXRT1015\middleware\mcu-boot\bin\Tools and image_enc tool to realize the BEE commander line method encryption operation, then use the MFGTool download the BEE encrypted code to the RT1015 external QSPI flash.     Because from SDK2.8.0, blhost, elftosb related tools will not be packed in the SDK middleware directly, the customer need to download it from this link: www.nxp.com/mcuboot   4.1 Commander line file preparation     Prepare one folder, put elftosb.exe, image_enc.exe,app file evkmimxrt1015_iled_blinky_0x60002000.s19,RemoveBinaryBytes.exe to that folder. RemoveBinaryBytes.exe is used to modify the bin file, it can be downloaded from this link: https://community.nxp.com/pwmxy87654/attachments/pwmxy87654/imxrt/8733/2/Test.zip (https://community.nxp.com/t5/i-MX-RT/RT1015-BEE-XIP-Step-Confirm/m-p/1070076/page/2)    Then prepare the following files: imx-flexspinor-normal-unsigned.bd imxrt1015_app_flash_sb_gen.bd burn_fuse.bd 4.1.1 imx-flexspinor-normal-unsigned.bd imx-flexspinor-normal-unsigned.bd files is used to generate the app file evkmimxrt1015_iled_blinky_0x60002000.s19 related boot .bin file, which is include the IVT header code: ivt_evkmimxrt1015_iled_blinky_0x60002000.bin ivt_evkmimxrt1015_iled_blinky_0x60002000_nopadding.bin bd file content is   /*********************file start****************************/ options {     flags = 0x00;     startAddress = 0x60000000;     ivtOffset = 0x1000;     initialLoadSize = 0x2000;     //DCDFilePath = "dcd.bin";     # Note: This is required if the default entrypoint is not the Reset_Handler     #       Please set the entryPointAddress to Reset_Handler address     // entryPointAddress = 0x60002000; }   sources {     elfFile = extern(0); }   section (0) { } /*********************file end****************************/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   4.1.2 imxrt1015_app_flash_sb_gen.bd    This file is used to configure the external QSPI flash, and realize the program function, normally use this .bd file to generate the .sb file, then use the MFGtool select this .sb file and download the code to the external flash.   /*********************file start****************************/ sources {     myBinFile = extern (0); }   section (0) {     load 0xc0000007 > 0x20202000;     load 0x0 > 0x20202004;     enable flexspinor 0x20202000;     erase  0x60000000..0x60005000;     load 0xf000000f > 0x20203000;     enable flexspinor 0x20203000;     load  myBinFile > 0x60000400; } /*********************file end****************************/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   4.1.3 burn_fuse.bd     BEE encryption operation need to burn the fuse map, but the fuse data is the one time operation from 0 to 1, here will separate the burn fuse operation, only do the burn fuse operation during the first time which the RT chip still didn’t be modified the fuse map. Otherwise, in the next operation, just modify the app code, don’t need to burn the fuse. Burn_fuse.bd is mainly used to configure the fuse data which need to burn the related fuse map, then generate the .sb file, and use the MFGTool burn it with the app together.   /*********************file start****************************/ # The source block assign file name to identifiers sources { }   constants { }   #                !!!!!!!!!!!! WARNING !!!!!!!!!!!! # The section block specifies the sequence of boot commands to be written to the SB file # Note: this is just a template, please update it to actual values in users' project section (0) {     # program SW_GP2     load fuse 0x76543210 > 0x29;     load fuse 0xfedcba98 > 0x2a;     load fuse 0x89abcdef > 0x2b;     load fuse 0x01234567 > 0x2c;         # Program BEE_KEY0_SEL     load fuse 0x00003000 > 0x6;     } /*********************file end****************************/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 4.2 BEE commander line operation steps  Create the rt1015_bee_userkey_gp2.bat file, the content is:   elftosb.exe -f imx -V -c imx-flexspinor-normal-unsigned.bd -o ivt_evkmimxrt1015_iled_blinky_0x60002000.bin evkmimxrt1015_iled_blinky_0x60002000.s19 image_enc.exe hw_eng=bee ifile=ivt_evkmimxrt1015_iled_blinky_0x60002000.bin ofile=evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted.bin base_addr=0x60000000 region0_key=0123456789abcdeffedcba9876543210 region0_arg=1,[0x60001000,0x2000,0] region0_lock=0 use_zero_key=1 is_boot_image=1 RemoveBinaryBytes.exe evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted.bin evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted_remove1K.bin 1024 elftosb.exe -f kinetis -V -c program_imxrt1015_qspi_encrypt_sw_gp2.bd -o boot_image_encrypt.sb evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted_remove1K.bin elftosb.exe -f kinetis -V -c burn_fuse.bd -o burn_fuse.sb pause‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ Fig 13 Fig 14 it mainly has 5 steps: 4.2.1 elftosb generate app file with IVT header elftosb.exe -f imx -V -c imx-flexspinor-normal-unsigned.bd -o ivt_evkmimxrt1015_iled_blinky_0x60002000.bin evkmimxrt1015_iled_blinky_0x60002000.s19 After this commander, will generate two files with the IVT header: ivt_evkmimxrt1015_iled_blinky_0x60002000.bin,ivt_evkmimxrt1015_iled_blinky_0x60002000_nopadding.bin Here, we will use the ivt_evkmimxrt1015_iled_blinky_0x60002000.bin 4.2.2 image_enc generate the app related BEE encrypted code image_enc.exe hw_eng=bee ifile=ivt_evkmimxrt1015_iled_blinky_0x60002000.bin ofile=evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted.bin base_addr=0x60000000 region0_key=0123456789abcdeffedcba9876543210 region0_arg=1,[0x60001000,0x2000,0] region0_lock=0 use_zero_key=1 is_boot_image=1 About the keyword meaning in the image_enc, we can run the image_enc directly to find it. Fig 15 This commander line run result will be the same as the MCUBootUtility configuration. The encryption area from 0X60001000, the length is 0x2000, more details, can refer to Fig 4. After the operation, we can get this file: evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted.bin   4.2.3 RemoveBinaryBytes remove the BEE encrypted file above 1024 bytes RemoveBinaryBytes.exe evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted.bin evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted_remove1K.bin 1024 This commaner will used to remove the BEE encrypted file, the above 0X400 length data, after the modification, the encrypted file will start from EKIB0 directly. After running it, will get this file: evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted_remove1K.bin   4.2.4 elftosb generate BEE encrypted app related sb file elftosb.exe -f kinetis -V -c program_imxrt1015_qspi_encrypt_sw_gp2.bd -o boot_image_encrypt.sb evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted_remove1K.bin This commander will use evkmimxrt1015_iled_blinky_0x60002000_bee_encrypted_remove1K.bin and program_imxrt1015_qspi_encrypt_sw_gp2.bd to generate the sb file which can use the MFGTool download the code to the external flash After running it, we can get this file: boot_image_encrypt.sb   4.2.5 elftosb generate the burn fuse related sb file elftosb.exe -f kinetis -V -c burn_fuse.bd -o burn_fuse.sb This commander is used to generate the BEE code related fuse bits sb file, this sb file will be burned together with the boot_image_encrypt.sb in the MFGTool. But after the fuse is burned, the next app modify operation don’t need to add the burn fuse operation, can download the add directly. After running it, can get this file: burn_fuse.sb   4.3 MFGTool downloading   MIMXRT1015-EVK board enter the serial downloader mode, find two USB cable, plug it in J41 and J9 to the PC. MFGTool can be found in folder: SDK_2.8.0_EVK-MIMXRT1015\middleware\mcu-boot\bin\Tools\mfgtools-rel   If need to burn the burn_fuse.sb, need to modify the ucl2.xml, folder path: \SDK_2.8.0_EVK-MIMXRT1015\middleware\mcu-boot\bin\Tools\mfgtools-rel\Profiles\MXRT1015\OS Firmware    Add the following list to realize it. <LIST name="MXRT1015-beefuse_DevBoot" desc="Boot Flashloader"> <!-- Stage 1, load and execute Flashloader -->        <CMD state="BootStrap" type="boot" body="BootStrap" file="ivt_flashloader.bin" > Loading Flashloader. </CMD>     <CMD state="BootStrap" type="jump"  onError = "ignore"> Jumping to Flashloader. </CMD> <!-- Stage 2, burn BEE related fuse using Flashloader -->      <CMD state="Blhost" type="blhost" body="get-property 1" > Get Property 1. </CMD> <!--Used to test if flashloader runs successfully-->     <CMD state="Blhost" type="blhost" body="receive-sb-file \"Profiles\\MXRT1015\\OS Firmware\\burn_fuse.sb\"" > Program Boot Image. </CMD>     <CMD state="Blhost" type="blhost" body="reset" > Reset. </CMD> <!--Reset device--> <!-- Stage 3, Program boot image into external memory using Flashloader -->       <CMD state="Blhost" type="blhost" body="get-property 1" > Get Property 1. </CMD> <!--Used to test if flashloader runs successfully-->     <CMD state="Blhost" type="blhost" timeout="15000" body="receive-sb-file \"Profiles\\MXRT1015\\OS Firmware\\ boot_image_encrypt.sb\"" > Program Boot Image. </CMD>     <CMD state="Blhost" type="blhost" body="Update Completed!">Done</CMD> </list>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍     If already have burned the Fuse bits, just need to update the app, then we can use MIMXRT1015-DevBoot   <LIST name="MXRT1015-DevBoot" desc="Boot Flashloader"> <!-- Stage 1, load and execute Flashloader -->        <CMD state="BootStrap" type="boot" body="BootStrap" file="ivt_flashloader.bin" > Loading Flashloader. </CMD>     <CMD state="BootStrap" type="jump"  onError = "ignore"> Jumping to Flashloader. </CMD> <!-- Stage 2, Program boot image into external memory using Flashloader -->       <CMD state="Blhost" type="blhost" body="get-property 1" > Get Property 1. </CMD> <!--Used to test if flashloader runs successfully-->     <CMD state="Blhost" type="blhost" timeout="15000" body="receive-sb-file \"Profiles\\MXRT1015\\OS Firmware\\boot_image.sb\"" > Program Boot Image. </CMD>     <CMD state="Blhost" type="blhost" body="Update Completed!">Done</CMD> </list>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ Which detail list is select, it is determined by the cfg.ini name item [profiles] chip = MXRT1015 [platform] board = [LIST] name = MXRT1015-DevBoot‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   Because my side do the MCUbootUtility operation at first, then the fuse is burned, so in the commander line, I just use MXRT1015-DevBoot download the app.sb Fig 16 We can find, it is burned successfully, click stop button, Configure the MIMXRT1015-EVK on board SW8 as 1-ON,2-OFF,3-ON,4-OFF, reset the board, we can find the on board LED is blinking, it means the commander line also can finish the BEE encryption successfully.   5  MCUXpresso Secure Provisioning BEE unsigned operation      This part will use the MCUXPresso Secure Provisioning tool to finish the BEE unsigned image downloading BEE unsigned image is just use the BEE, no certification. 5.1 Tool downloading MCUXPresso Secure Provisioning download link is: https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-secure-provisioning-tool:MCUXPRESSO-SECURE-PROVISIONING Download it and install it, it’s better to read the tool document at first: C:\nxp\MCUX_Provi_v2.1\MCUXpresso Secure Provisioning Tool.pdf 5.2 Operation Steps Step1: Create the new tool workspace File->New Workspace, select the workspace path. Fig 17 Step2: Chip boot related configuration Fig 18 Here, please note, the boot type need to select as XIP Encrypted(BEE User Keys) unsigned, which is not added the HAB certification function. Step3: USB connection Connect Select USB, it will use the USB HID to connect the board in serial download mode, so the MIMXRT1015-EVK board need insert the USB port to the J9, and the board need to enter the serial download mode: SW8:1-ON,2-OFF,3-OFF,4-ON Connect Test Connection Button, the connection result is: Fig 19 We can see the connection is OK, due to this board has done the BEE operation in the previous time, so the related BEE fuse is burned, then we can find the BEE key and the key source SW-GP2 fuse already has data. Step4: image selection Just like the previous content, prepare one app image. Step 5: XIP Encryption(BEE user keys) configuration Fig 20 Here, it will need to select which engine, we select Engine0, BEE engine KEY use zero key, key source use the SW-GP2, then the detail user key data: 0123456789abcdeffedcba9876543210 Will be wrote to the swGp2 fuse area. Because my board already do that fuse operation, so here it won’t burn the fuse again. Step 6: build image Fig 21 Here, we will find, after this operation, the tool will generate 5 files: 1) evkmimxrt1015_iled_blinky_0x60002000.bin 2) evkmimxrt1015_iled_blinky_0x60002000_bootable.bin 3) evkmimxrt1015_iled_blinky_0x60002000_bootable_nopadding.bin 4) evkmimxrt1015_iled_blinky_0x60002000_nopadding.bin 5) evkmimxrt1015_iled_blinky_0x60002000_nopadding_ehdr0.bin 1), 2), 3) is the plaintext file, 1) and 2) are totally the same, this file maps the data from base 0, from 0x1000 it is IVT+BD+DCD, from 0X2000 is app, so these files are the whole image, just except the FlexSPI Configuration block data, which should put from base address 0. 3) it is the 2) image just delete the first 0X1000 data, and just from IVT+BD+DCD+app. 4) ,5) is the BEE encrypted image, 4) is related to 3), just the BEE encrypted image, 5) is the EKIB0, EPRDB0 data, which should be put in the real address from 0X60000400, it is the BEE Encrypted Key Info Block 0 and Encrypted Protection Region Descriptor Block 0 data, as we just use the engine0, so just have the engin0 data. In fact, the BEE whole image contains : FlexSPI Configuration block data +IVT+BD+DCD+APP FlexSPI Configuration block data is the plaintext, but from 0X60001000 to 0X60002fff is the encrypted image. Step 7: burn the encrypted image Fig 22 Click the Write Image button, to finish the BEE image program. Here, just open the bee_user_key0.bin, we will find, it is just the user key data which is defined in Fig 20, which also should be written to the swGp2 fuse. Check the log, we will find it mainly these process: Erase image from 0x60000000, length is 0x5000. Generate the flexSPI Configuration block data, and download from 0x60000000 Burn evkmimxrt1015_iled_blinky_0x60002000_nopadding_ehdr0.bin to 0X60000400 Burn evkmimxrt1015_iled_blinky_0x60002000_nopadding.bin to 0x60001000 Modify the MIMXRT1015-EVK SW8:1-ON,2-OFF,3-ON,4-OFF, reset or repower on the board, we will find the on board led is blinking, it means the bee encrypted image already runs OK. Please note: SW8_1 is the Encrypted XIP pin, it must be enable, otherwise, even the BEE encrypted image is downloaded to the external flash, but the boot will be failed, as the ROM will use normal boot not the BEE encrypted boot. So, SW8_1 should be ON.    Following pictures are the BEE encrypted image readout file to compare with the tool generated files. Fig 23 Fig 24 Fig 25 Fig 26 Fig 27 About the MCUBootUtility lack the BEE tool image_enc.exe, we also can use the MCUXPresso Secure Provisioning’s image_enc.exe: Copy: C:\nxp\MCUX_Provi_v2.1\bin\tools\image_enc\win\ image_enc.exe To the MCUbootUtility folder: NXP-MCUBootUtility-3.2.0\tools\image_enc2\win Attachment also contains the video about this tool usage operation.    
View full article