S32K Knowledge Base

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

S32K Knowledge Base

Labels

Discussions

Sort by:
Hi all,   Many customers complained about the K3 FlexIO I2S can not support continuous transferring because there is a gap time between 2 times of invoking SendData. This gap time will break the audio continuity and bring jitters. It is gapped by the transfer API closing and re-entry time cost.   To avoid this gap and implement a real continuous transferring, we made some changes with eDMA configurations. Finally, it works!   Besides, we also enabled eDMA half-complete interrupt to support double-buffer (ping-pong buffer) operation for user's further development.   Attachments are the example projects and corresponding introduction slides, please kindly check if you are interested in. Any problem, just let me know. Welcome your comments here.   Best Regards, Shuailin Li NXP GPIS, AE
View full article
************************************************************************************************************************** * Detailed Description: * * Connect PTC24 (PWM) to PTC25 (IC) * * PWM signal generated by EMIOS_1_ch0 (in OPWFMB mode) is measured by EMIOS_1_ch_1 (IPWM mode). * * EMIOS_1 global global clock (core clock = 48MHz) prescaled in EMIOS_Mcl driver (/48) = 1MHz. * * BUS_A generated by EMIOS_1_ch_23 * Tick = 10us (1MHz global clock prescaled by 10 = 100kHz) * * PWM (OPWFMB), EMIOS_1_ch_0, PTC24 * Tick = 10us (1MHz global clock prescaled by 10 = 100kHz) * * IC (IPWM), EMIOS_1_ch_1, PTC25 * Clocked by BUS_A * Tick = 10us * * ------------------------------------------------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K344 * Debugger: S32DS 3.4, PEMicro Multilink rev.C * Target: internal_FLASH **************************************************************************************************************************
View full article
This article is written in Chinese. It is mainly for the disty and mass market customers in local China. It is useful for the the developers who is newly in touch with S32K1, and will help them install several software of S32K1, otherwise it may waste a lot of time.     S32DS中快速搭建S32K1的开发环境 一.背景 我最近换装了新电脑,需要重新安装S32DS,发现存在很多问题。尤其是对比之前的安装过程,发现官网的很多链接已经失效,甚至有一定的迷惑性。 最新的S32K1安装包比较隐蔽,而且安装存在前后依赖,对于刚接触NXP S32系列的新手非常不友好,所以写这篇文档总结一下典型的问题和解决方法。 同时也希望提供一个check的思路和步骤,在后续新版本发布时,升级IDE的时候更方便找到合适的安装包。 二.S32DS中各个包依赖关系解析 在S32DS中,每一个系列的MCU,总共需要安装两个插件包,一个是基础依赖包,一个是SDK(也叫RTD,同一个意思)。 1.基础依赖包 这个包对应S32DS版本,比如当前的3.4.3,官网可以下载离线版,一般大小在3GB左右,会更新S32DS中的很多组件,如下图1所示:            图1 尤其需要关注图1中红框的内容,没有这个development package的话,是无法进行对应MCU的debug。 图1中安装的包,对应到S32DS中安装的内容如图2所示:            图2 2.RTD安装包(与SDK同义) 这个包对应于RTD版本,也会标识AutoSAR的版本,比如最新的2.0.0,AutoSar 4.4,如图3所示:           图3 基础依赖包与RTD安装包存在前后依赖关系,如果不安装基础依赖包直接安装RTD,在安装时会报错。另外,我们下载的RTD包,即使写明是K3,里面也会包含K1的RTD,这点需要注意。如果此时还没有装K1的development package,就会出错。 三.S32K1开发环境搭建 官网对于S32K3的软件划分为standard software和reference software,其中S32DS和基础依赖包在standard software中,可以很方便的找到。 但S32K1的官网却仅有一个reference software,页面也只能找到几个RTD(或SDK)链接:                                                                             图4 这里面所有的链接都不是我们需要的,全是RTD。问题就出在这里,K1的网页中没有K1的基础依赖包!而前面讲过,缺基础依赖包会导致RTD也无法安装。经过我研究,K1的基础依赖包隐藏的非常深,可以通过两个方法找到: 从S32K1的reference software进去,然后重新点击product list,如下图5所              图5         进入如下页面,如图6所示,这里最能看出来,针对K1的界面很不友好,需要点最底下的NXP Software.              图6 在NXP.com官网首页搜索栏直接搜S32DS,找到S32 Design Studio for S32 Platform(注意不要选成for ARM或或者for PowerPC),从S32DS的主界面进入,然后一直下拉,找到S32DS service pack 1,这个才是K1的,如图7所示:                 图7 这个链接更加隐蔽,要在40多个选项里挨个找。   经过上面两个方法,都可以进入图8所示的界面,然后再按图8所示操作:              图8   这回终于到了最终可以下载S32K1基础依赖包的地方,如图9所示。我们需要重点关注一下命名,SW32开头的,会包含所有S32的development package,包括K1,K3,G;SW32K1开头的,仅有K1,同理如果你在K3的界面中,可以看到SW32K3开头的。            图9 下载最新版本的S32K1基础依赖包,然后再安装RTD,大功告成。
View full article
Some customers inquire how to use FreeMASTER with S32K3. But there is no exists example projects which demonstrate usage of the FreeMASTER serial communication driver in S32K3 Real Time Drivers at the moment. So this article will introduce how to use FreeMaster SDKs in S32K3 RTD 0.9.0. Download S32DS \ S32K3 Development Package \ RTD (SDK) \ FreeMASTER Driver Login your account on NXP website, and download the S32K3 Standard software from TOOLS &SOFTWARE of S32K3 webpage. If you have already installed the S32DS3.4 \ S32K3 Development Package 3.4.0 \ RTD 0.9.0, then you can skip the following part and start directly from 4.Install FreeMASTER Driver 3.0 for S32K3 Install S32K3 Development Package 3.4.0 After install the S32 Design Studio v3.4, we should install S32K3 Development Package 3.4.0(SW32K3_S32DS_3.4.0_D2012.zip): go to menu "Help" -> "Install New Software" and click on "Add..." button Here we uncheck S32 Design Studio S32K3 SDK (RTD S32K3 0.8.1), because we will install the newer version S32K3 RTD 0.9.0 later. Install S32K3 Real Time Drivers Version 0.9.0 S32K3 Real Time Drivers Version 0.9.0 can be installed by refer the Offline Package Installation Setup of S32DS Extensions & Updates: Explanation and How To Use. Install FreeMASTER Driver 3.0 for S32K3 Attach FreeMASTER_S32K3 to S32K344_UART_Printf_Sample_090_34 The reason for choosing the S32K344_UART_Printf_Sample_090_34 project to demonstrate the combination of FreeMaster SDKs is that the project has already configured the LPUART of the S32K3X4EVB-Q257 development board. Select LPUART peripheral as host communication Through the description in the Requirements and Release Description chapter of FreeMASTER Driver Release Notes(FMSTRS32K3RN), we can see that currently only UART interface is supported. The S32K3 FreeMASTER 3.0 version 1.0.0 only support NXP GCC 6.3 or 9.2 for ARM at the moment, but the latest S32K3 Real Time Drivers Version 1.0.0 is based on NXP GCC 10.2.0. This is the reason why RTD 0.9.0 is selected in this article.  The README.txt also shows that: Current package provides FreeMASTER Communication Driver support for S32K344 over LPUART module   LPUART13 is selected in this project for S32K3X4EVB-Q257, so we need to define the base address for FreeMASTER: #define FMSTR_LPUART_BASE           0x404A0000 Modify the main function according to the README.txt: Connect FreeMASTER3.1 to S32K3X4EVB-Q257 board Here we can see that the FreeMASTER3.1 is connected to S32K3X4EVB-Q257 board.  
View full article
[RTD400HF01 LLD]K312 No HSE secure debug operation 1. Abstract The S32K3 chip has rich encryption functions. For encryption, an independent arm core is even allocated for HSE. HSE firmware needs to be installed separately. For the encryption debug interface, there are usually two ways: Install HSE firmware to do static or dynamic secure Do static secure without installing HSE firmware The default chip does not install HSE firmware. In order to verify the secure debug, this article will use the RTD400HF01 version on the K312 chip to do static secure debug interface without installing HSE firmware. Other K3 chips are similar. The outline of this article is as follows:  Fig 1 2. Hardware prepare For the hardware, you can use any K3 board, such as the K312-EVB development board, or a self-developed board. In order to facilitate chip replacement in this article, an evaluation board with a socket is used:    Fig 2 If need to configure to the K312, the board jumper need to do the following configuration: J92:2-3,J28:2-3 ,J64:2-3  ,J114:2-3,J71:2-3  ,J118:2-3,J57:2-3 ,J72:2-3 ,J99:2-3 3. Secure debug interface 3.1 flash code prepare     The flash controller of K3 is a PFLASH module. The chip comes with c40asf flash memory. Different K3 chips have different flash sizes and block numbers. Since the flash in the chip cannot implement the RWW function, when doing flash operations, you need to consider RWW and copy the flash operation code to the internal RAM for execution.     This article will take the LLD routine C40_Ip_Example routine of the RTD400HF01 version as the starting point. Since the RTD400HF01 version does not directly come with the K312 example, you first need to create a new K312 project, and then configure the LLD configuration by yourself. You can refer to the relevant LLD configuration of K344, but you need to pay attention to the clock situation to meet the requirements of K312. This article uses the option B clock mode, the clock is 120Mhz. The most feasible way to verify the code for successful flash operation is to be able to operate the flash area and the code area in one block. Of course, it is necessary to pay attention to the flash sector and app code to be erased and written. Do not overlap. This can be checked according to the map file. For example: #define EXAMPLE_SECTOR_START_ADDR       (0x004FE000) #define EXAMPLE_SECTOR_TEST             (C40_CODE_ARRAY_0_BLOCK_0_S127)    Fig 3    Usually, in order to consider a larger margin, you can directly exceed the maximum hex value compiled, and then take the last sector of the current block to ensure that this address and the compiled size do not overlap in sectors.     For flash operations considering RWW, there are two methods for RTD500/RTD400. One thing is that it is not enough to just put the Flash operation code into RAM. Here are two methods that can be run, both of which have been tested and can work stably: 3.1.1 flash code copy to RAM and wait the controller is idle This requires two steps: first put the C40_Ip.c, C40_Ip.h related flash operation code into RAM, then wait for the flash controller to be idle before doing other operations. (1) Open C40_Ip.c in the RTD/src folder Two places need to be modified: Modify the start of the file:               #define MEM_43_INFLS_START_SEC_CODE   to:         #define MEM_43_INFLS_START_SEC_RAMCODE    Modify the file ending area:     #define MEM_43_INFLS_STOP_SEC_CODE To :     #define MEM_43_INFLS_STOP_SEC_RAMCODE (2)Open C40_Ip.h in the RTD/include folder Two places need to be modified: Modify the beginning of the file:          #define MEM_43_INFLS_START_SEC_CODE   To :         #define MEM_43_INFLS_START_SEC_RAMCODE    Modify the file ending area:     #define MEM_43_INFLS_STOP_SEC_CODE To :     #define MEM_43_INFLS_STOP_SEC_RAMCODE The purpose of doing this is to put all the functions in C40_Ip into RAM. After compiling, check the ramcode area in the map file:  Fig 4 As you can see, after the above modification, all relevant C40 functions have been put into the internal RAM. But please note that if you only do this and directly operate the flash, especially when erasing block0, hard fault will occur. You also need to wait for the FLASH controller to be idle. Add a code to wait for the FLASH controller to be idle in main, and also put it in RAM. After operating the flash erase or write, call the function that waits for the FLASH controller to be idle. Before operating the flash code, you also need to call : C40_Ip_SetAsyncMode(FALSE); Refer to the following code: #define MEM_43_INFLS_START_SEC_RAMCODE #include "Mem_43_INFLS_MemMap.h" void MemInfls_AccessCodeLoadToRam(void); #define MEM_43_INFLS_STOP_SEC_RAMCODE #include "Mem_43_INFLS_MemMap.h" #define MEM_43_INFLS_START_SEC_RAMCODE #include "Mem_43_INFLS_MemMap.h" /* @violates @ref fls_flash_c_REF_20 Object/function previously declared */ void MemInfls_AccessCodeLoadToRam(void) { #if (C40_IP_TIMEOUT_SUPERVISION_ENABLED == STD_ON) uint32 ValueTimeOut = C40_Ip_u32TimeoutTicks; uint32 WaitedTicks; #endif /* Start internal erase/program sequence */ C40_Ip_pFlashBaseAddress->MCR |= FLASH_MCR_EHV_MASK; /* Wait until operation finishes or write/erase timeout is reached */ while (0U == (C40_Ip_pFlashBaseAddress->MCRS & FLASH_MCRS_DONE_MASK)) { #if (C40_IP_TIMEOUT_SUPERVISION_ENABLED == STD_ON) ValueTimeOut--; if (0U == ValueTimeOut) { break; } #endif } /* Disable HV to finalize/abort the operation */ C40_Ip_pFlashBaseAddress->MCR &= ~FLASH_MCR_EHV_MASK; /* Wait until done or abort timeout is reached */ while (0U == (C40_Ip_pFlashBaseAddress->MCRS & FLASH_MCRS_DONE_MASK)) { #if (C40_IP_TIMEOUT_SUPERVISION_ENABLED == STD_ON) ValueTimeOut--; if (0U == ValueTimeOut) { break; } #endif } #if (C40_IP_TIMEOUT_SUPERVISION_ENABLED == STD_ON) /* Update the timeout counter */ WaitedTicks = C40_Ip_u32TimeoutTicks - ValueTimeOut; C40_Ip_u32ElapsedTicks += WaitedTicks; C40_Ip_u32CurrentTicks += WaitedTicks; #endif } #define MEM_43_INFLS_STOP_SEC_RAMCODE #include "Mem_43_INFLS_MemMap.h"    Main code related erase and program is: #define EXAMPLE_SECTOR_START_ADDR (0x004FE000) #define EXAMPLE_SECTOR_TEST (C40_CODE_ARRAY_0_BLOCK_0_S127) C40_Ip_SetAsyncMode(FALSE); t_SectorAddr = EXAMPLE_SECTOR_START_ADDR; t_SectorNumber = EXAMPLE_SECTOR_TEST; /* Unlock sector */ if (C40_IP_STATUS_SECTOR_PROTECTED == C40_Ip_GetLock(t_SectorNumber)) { C40_Ip_ClearLock(t_SectorNumber, EXAMPLE_MASTER_ID); } /* Erase sector */ C40_Ip_MainInterfaceSectorErase(t_SectorNumber, EXAMPLE_MASTER_ID); MemInfls_AccessCodeLoadToRam(); do { t_ReturnValue = C40_Ip_MainInterfaceSectorEraseStatus(); } while (C40_IP_STATUS_BUSY == t_ReturnValue); Example_CheckAssert(t_ReturnValue == C40_IP_STATUS_SUCCESS); /* Write data */ C40_Ip_MainInterfaceWrite(t_SectorAddr, t_BufferSize, TxBuffer, EXAMPLE_MASTER_ID); MemInfls_AccessCodeLoadToRam(); do { t_ReturnValue = C40_Ip_MainInterfaceWriteStatus(); } while (C40_IP_STATUS_BUSY == t_ReturnValue); Example_CheckAssert(t_ReturnValue == C40_IP_STATUS_SUCCESS); Compile the code, burn the code and test the results as follows:  Fig 5  Fig 6    Fig 7   3.1.2 link modify the file to RAM     The above method requires more changes, and special waiting code needs to be added. Here is another method, which can directly modify the link file to directly drop all related .o files into RAM at once, and then for the user program, the RTD driver does not need to modify or add additional code. Open the project Project_Settings->Linker_Files->linker_flash_s32k312.ld Two points need to be modified: (1)  .pflash Modify the following code:   .pflash : { KEEP(*(.boot_header)) . = ALIGN(8192); /* The minimum erase size of C40 Flash IP is 8kb */ __text_start = .; __interrupts_init_start = .; KEEP(*(.intc_vector)) . = ALIGN(4); __interrupts_init_end = .; KEEP(*(.core_loop)) . = ALIGN(4); *(.startup) . = ALIGN(4); *(.systeminit) . = ALIGN(4); *(.text.startup) . = ALIGN(4); *(EXCLUDE_FILE (*C40_Ip.o *OsIf_Timer.o *OsIf_Timer_System.o) .text) *(EXCLUDE_FILE (*C40_Ip.o *OsIf_Timer.o *OsIf_Timer_System.o) .text*) . = ALIGN(4); *(EXCLUDE_FILE (*C40_Ip.o *OsIf_Timer.o *OsIf_Timer_System.o) .mcal_text) . = ALIGN(4); *(.acmcu_code_rom) . = ALIGN(4); __acfls_code_rom_start = .; *(.acfls_code_rom) . = ALIGN(4); __acfls_code_rom_end = .; __acmem_43_infls_code_rom_start = .; *(.acmem_43_infls_code_rom) . = ALIGN(4); __acmem_43_infls_code_rom_end = .; KEEP(*(.init)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); *(.rodata) *(.rodata*) . = ALIGN(4); *(.mcal_const_cfg) . = ALIGN(4); *(.mcal_const) . = ALIGN(4); __init_table = .; KEEP(*(.init_table)) . = ALIGN(4); __zero_table = .; KEEP(*(.zero_table)) } > int_pflash (2).pflash section add the following code .itcm_text : AT(__tcm_code_rom_start) { . = ALIGN(4); __itcm_start__ = .; *(.itcm_text*) . = ALIGN(4); KEEP(*C40_Ip.o (.mcal_text*)) KEEP(*C40_Ip.o (.text*)) KEEP(*C40_Ip.o (.text)) KEEP(*OsIf_Timer.o (.mcal_text*)) KEEP(*OsIf_Timer.o (.text*)) KEEP(*OsIf_Timer.o (.text)) KEEP(*OsIf_Timer_System.o (.mcal_text*)) KEEP(*OsIf_Timer_System.o (.text*)) KEEP(*OsIf_Timer_System.o (.text)) . = ALIGN(4); __itcm_end__ = .; } > int_itcm From here, we can see that in fact, not only the C40 code needs to be copied to RAM, but also the OsIf_Timer and OsIf_Timer_System related codes need to be put into RAM. The test results are the same as those in Figure 5.6.7, and the erase and write actions of the corresponding block0 flash sector can be realized. 3.2  burn key to UTEST 0X1B000080 For secure debug, there are two static key addresses in the UTEST area: 0X1B000080, 0X1B000370. 0X1B000370 is the static encryption key address for use after the HSE firmware is installed. 0X1B000080 is the static encryption key address without HSE firmware.  Fig 8 So the following operation needs to be performed to burn the key to the address of UTEST 0X1B000080. After the above flash preparation, it is very clear to burn the key, but there is no need to erase it. When it is determined that the key address is not all 0XFF, the key operation can be performed directly. The code is as follows: Generate->include->C40_Ip_Cfg.h #define C40_IP_MAX_VIRTUAL_SECTOR              (272U)//(271U) If this is not modified, it will get stuck when executing sector C40_Ip_GetLock. #define C40_UTEST_ARRAY_0_S000 (272U) /* 0x1B000000 */ #define FLS_SECTOR_ADDR 0x1B000080U #define FLS_SECTOR_TEST C40_UTEST_ARRAY_0_S000 uint8 ADKP_Buffer[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15}; if( (IP_DCM->DCMLCC & 0x77) == 0x33 ) // check LC is CUST_DEL or not { #if 1 //read the UTEST password data, if 0XFF, write. /* Read data */ t_SectorAddr = FLS_SECTOR_ADDR; t_SectorNumber = FLS_SECTOR_TEST; t_ReturnValue = C40_Ip_Read(t_SectorAddr, 16, RxBuffer); Example_CheckAssert(t_ReturnValue == C40_IP_STATUS_SUCCESS); KeyEmptyFlag = 1; for(uint32_t i=0; i<16; i++) { if(RxBuffer[i] != 0XFF) { KeyEmptyFlag = 0; break; } } //write ADKP to UTEST, just write once! if(KeyEmptyFlag == 1) { /* Unlock sector */ if (C40_IP_STATUS_SECTOR_PROTECTED == C40_Ip_GetLock(t_SectorNumber)) { C40_Ip_ClearLock(t_SectorNumber, FLS_MASTER_ID); } /* Write data */ C40_Ip_MainInterfaceWrite(FLS_SECTOR_ADDR, 16, ADKP_Buffer, FLS_MASTER_ID); MemInfls_AccessCodeLoadToRam();//kerry do { t_ReturnValue = C40_Ip_MainInterfaceWriteStatus(); } while (C40_IP_STATUS_BUSY == t_ReturnValue); Example_CheckAssert(t_ReturnValue == C40_IP_STATUS_SUCCESS); //Power_Ip_PerformReset(&Power_Ip_HwIPsConfigPB); } #endif Test conditions before Key burning:  Fig 9 Test results after Key burning:  Fig 10 It can be seen that key: HEX 00010203040506070809101112131415 is successfully burned into the UTEST 0X1B000080 area. 3.3 Program IVT lifecyle related flash area To really make secure debug work, the lifecycle needs to be evolved to non-CUST_DEL and FA. This article tests the evolution of LC to the IN_FIELD stage: LCW = 0xDADADADA advances LC to OEM_PROD LCW = 0xBABABABA advances LC to IN_FIELD The address corresponding to LC (lifecyle) is the offset 0X24 of IVT, and must be 4-byte aligned. You can specify the address of IVT->LC to a flash area, and then burn the corresponding flash value to the IN_FIELD value: 0xBABABABA Evolution method: (1) Set the flash address of IVT LC (2) Write the IN_FIELD value 0xBABABABA to the corresponding flash address (3) Software reset After evolution, you can also check whether the evolution is successful by checking the LC slot combination starting from address 0X1B000220 in the UTEST area. Of course, after the evolution is successful, the debug interface will also be locked, which can be unlocked to view. In addition, you can also view the evolved LC results through the DCM_DCMLCC register.  Fig 11 Here are the relevant codes: (1)Project_Settings->Startup_Code->startup_cm7.s #define LF_CONFIG_ADDR (0x00500000U)/*(0)*/ .section ".boot_header","ax" /*00h*/ .long SBAF_BOOT_MARKER /* IVT marker */ /*04h*/ .long (CM7_0_ENABLE << CM7_0_ENABLE_SHIFT) | (CM7_1_ENABLE << CM7_1_ENABLE_SHIFT) | (CM7_2_ENABLE << CM7_2_ENABLE_SHIFT) /* Boot configuration word */ /*08h*/ .long 0 /* Reserved */ /*0Ch*/ .long CM7_0_VTOR_ADDR /* CM7_0 Start address */ /*10h*/ .long 0 /* Reserved */ /*14h*/ .long CM7_1_VTOR_ADDR /* CM7_1 Start address */ /*18h*/ .long 0 /* Reserved */ /*1Ch*/ .long CM7_2_VTOR_ADDR /* CM7_2 Start address */ /*20h*/ .long 0 /* Reserved */ /* .long XRDC_CONFIG_ADDR*/ /* XRDC configuration pointer */ /*24h*/ .long LF_CONFIG_ADDR /* Lifecycle configuration pointer */ /*28h*/ .long 0 /* Reserved */ It can be seen that the flash address specified by IVT offset 0X24 is 0X00500000 (2) Add flash0X00500000 area and write code #define FLS_SECTOR_ADDR_LC (0x00500000U) #define FLS_SECTOR_ADDR_LC_TEST (C40_CODE_ARRAY_0_BLOCK_1_S128) uint8 lcwValue[8] = {0xBA,0xBA,0xBA,0xBA,0x00,0x00,0x00,0x00}; t_SectorAddr = FLS_SECTOR_ADDR_LC; t_SectorNumber = FLS_SECTOR_ADDR_LC_TEST; t_ReturnValue = C40_Ip_Read(t_SectorAddr, 16, RxBuffer); Example_CheckAssert(t_ReturnValue == C40_IP_STATUS_SUCCESS); LCEmptyFlag = 1; for(uint32_t i=0; i<16; i++) { if(RxBuffer[i] != 0XFF) { LCEmptyFlag = 0; break; } } //write LC, just write once! if(LCEmptyFlag == 1) { if (C40_IP_STATUS_SECTOR_PROTECTED == C40_Ip_GetLock(t_SectorNumber)) { C40_Ip_ClearLock(t_SectorNumber, EXAMPLE_MASTER_ID); } /* Write data */ C40_Ip_MainInterfaceWrite(t_SectorAddr, 8, lcwValue, FLS_MASTER_ID);//IN FIELD MemInfls_AccessCodeLoadToRam();//kerry do { t_ReturnValue = C40_Ip_MainInterfaceWriteStatus(); } while (C40_IP_STATUS_BUSY == t_ReturnValue); Example_CheckAssert(t_ReturnValue == C40_IP_STATUS_SUCCESS); Power_Ip_PerformReset(&Power_Ip_HwIPsConfigPB); } Of course, it should be noted here that if the corresponding flash address has been written with other values, you must first perform an erase operation before writing, or erase the entire chip once before downloading the code. The test results are as follows: Before LC evolution: The 16 bytes of 0X1B000220 are the location of LC slot1. It can be seen that LC slot1 CUST_DEL corresponds to the Active state: that is, the lower 64 bits are Marked, and the upper 64 bytes are Erased Mared: 0X55AA_50AF_55AA_50AF Erased: 0XFFFF_FFFF_FFFF_FFFF The other LC slot2, LC slot3, LC slot4, LC slot5 are all Erased. Figure 8 and Figure 11 can help understand.  Fig 12 IVT LC  related flash 0X00500000 data result:  Fig 13 3.4 SW reset The software reset code is as follows: Power_Ip_PerformReset(&Power_Ip_HwIPsConfigPB); After the software reset, you can see the PE Multilink connection results as follows:  Fig 14 The results of JLINK locking are as follows:  Fig 15 The results of the Lauterbach lock are as follows:  Fig 16 So far, the K312 debug interface has been encrypted. The following will explain how to decrypt it. 4. unlock debug interface 4.1 PE Multilink unlock For PE Multilink, the decryption link has been given from the encryption. You can refer to the following link of the PE official website: https://www.pemicro.com/blog/index.cfm?post_id=216  for detailed tutorials. You need to download the python script: http://www.pemicro.com/downloads/download_file.cfm?download_id=450  then unzip and open: \supportFiles_ARM\supportFiles_ARM\NXP\S32K3xx\ authenticate_password_mode.py  Fig17 Save the script, open the computer cmd command window, enter the script path, and enter: python authenticate_password_mode.py The decryption result is as follows:  Fig 18 As you can see, the decryption is complete. At this point, you can download a simple project to try, you can directly download the code and enter debug mode. Of course, if the power is turned off and then on again, you need to decrypt again. In your new app project, please modify the device to the : S32K312-SECUREDEBUG, otherwise, if you just use the S32K312, it will always report the secure issues. 3.2 Lauterbach unlock Prepare one .cmm file, then change the content to the following content: Global &SDAP_AUTHSTTS Global &SDAP_AUTHCTL Global &SDAP_KEYCHAL_0 Global &SDAP_KEYCHAL_1 Global &SDAP_KEYCHAL_2 Global &SDAP_KEYCHAL_3 Global &SDAP_KEYCHAL_4 Global &SDAP_KEYCHAL_5 Global &SDAP_KEYCHAL_6 Global &SDAP_KEYCHAL_7 GLOBAL &UID0 &UID1 Global &SDAP_AUTHSTTS_Read GLOBAL &CHAL0 &CHAL1 &CHAL2 &CHAL3 &CHAL4 &CHAL5 &CHAL6 &CHAL7 SYStem.CPU S32K312-M7 sys.mode prepare &SDAP_BASE_ADDRESS=0x40000700 &SDAP_AUTHSTTS = &SDAP_BASE_ADDRESS &SDAP_AUTHCTL = &SDAP_BASE_ADDRESS+0x4 &SDAP_KEYCHAL_0 = &SDAP_BASE_ADDRESS+0x10 &SDAP_KEYCHAL_1 = &SDAP_BASE_ADDRESS+0x14 &SDAP_KEYCHAL_2 = &SDAP_BASE_ADDRESS+0x18 &SDAP_KEYCHAL_3 = &SDAP_BASE_ADDRESS+0x1C &SDAP_KEYCHAL_4 = &SDAP_BASE_ADDRESS+0x20 &SDAP_KEYCHAL_5 = &SDAP_BASE_ADDRESS+0x24 &SDAP_KEYCHAL_6 = &SDAP_BASE_ADDRESS+0x28 &SDAP_KEYCHAL_7 = &SDAP_BASE_ADDRESS+0x2C &SDAP_KEYRESP_0 = &SDAP_BASE_ADDRESS+0x40 &SDAP_KEYRESP_1 = &SDAP_BASE_ADDRESS+0x44 &SDAP_KEYRESP_2 = &SDAP_BASE_ADDRESS+0x48 &SDAP_KEYRESP_3 = &SDAP_BASE_ADDRESS+0x4C &SDAP_KEYRESP_4 = &SDAP_BASE_ADDRESS+0x50 &SDAP_KEYRESP_5 = &SDAP_BASE_ADDRESS+0x54 &SDAP_KEYRESP_6 = &SDAP_BASE_ADDRESS+0x58 &SDAP_KEYRESP_7 = &SDAP_BASE_ADDRESS+0x5C &SDAP_UID0 = &SDAP_BASE_ADDRESS+0x70 &SDAP_UID1 = &SDAP_BASE_ADDRESS+0x74 &SDAP_DBGENCTRL = &SDAP_BASE_ADDRESS+0x80 &SDAP_SDAAPRSTCTRL = &SDAP_BASE_ADDRESS+0x90 &SDAP_SDAAPGENCTRL0 = &SDAP_BASE_ADDRESS+0xA4 &SDAP_DAP_GEN1_CTRL = &SDAP_BASE_ADDRESS+0xB4 ;prepare the key value ;sample adkp_value 5eba18b957523a0c10839b84c481f379 ;need byte sway &arg1 = 0x03020100 &arg2 = 0x07060504 &arg3 = 0x11100908 &arg4 = 0x15141312 &arg5 = 0x00000000 &arg6 = 0x00000000 &arg7 = 0x00000000 &arg8 = 0x00000000 ;Enable SDAP Based Debug Authorization data.set EDBG:&SDAP_SDAAPGENCTRL0 %LE %Long 0x00000001 local &rdata ;&rdata=Data.long(EDBG:&SDAP_AUTHSTTS)&0x00000001 ;while &rdata!=0x1 ;( ; &rdata=Data.long(EDBG:&SDAP_AUTHSTTS)&0x00000001 ;) &UID0=Data.long(EDBG:&SDAP_UID0) &UID1=Data.long(EDBG:&SDAP_UID1) &CHAL0=Data.long(EDBG:&SDAP_KEYCHAL_0) &CHAL1=Data.long(EDBG:&SDAP_KEYCHAL_1) &CHAL2=Data.long(EDBG:&SDAP_KEYCHAL_2) &CHAL3=Data.long(EDBG:&SDAP_KEYCHAL_3) &CHAL4=Data.long(EDBG:&SDAP_KEYCHAL_4) &CHAL5=Data.long(EDBG:&SDAP_KEYCHAL_5) &CHAL6=Data.long(EDBG:&SDAP_KEYCHAL_6) &CHAL7=Data.long(EDBG:&SDAP_KEYCHAL_7) print "UID0 is &UID0" print "UID1 is &UID1" data.set EDBG:&SDAP_KEYRESP_0 %LE %Long &arg1 data.set EDBG:&SDAP_KEYRESP_1 %LE %Long &arg2 data.set EDBG:&SDAP_KEYRESP_2 %LE %Long &arg3 data.set EDBG:&SDAP_KEYRESP_3 %LE %Long &arg4 data.set EDBG:&SDAP_KEYRESP_4 %LE %Long &arg5 data.set EDBG:&SDAP_KEYRESP_5 %LE %Long &arg6 data.set EDBG:&SDAP_KEYRESP_6 %LE %Long &arg7 data.set EDBG:&SDAP_KEYRESP_7 %LE %Long &arg8 ;Writing SDA AP AUTHCTL.HSEAUTHREQ data.set EDBG:&SDAP_AUTHCTL %LE %Long 0x00000001 wait 1ms &SDAP_AUTHSTTS_Read = Data.long(EDBG:&SDAP_AUTHSTTS) print "SDAP_AUTHSTTS is &SDAP_AUTHSTTS_Read" local &rdata1 &rdata1 = Data.long(EDBG:&SDAP_AUTHSTTS)&0x60000004 print "rdata1 is &rdata1" ;IF(&SDAP_AUTHSTTS_Read==0x60000005) IF (&rdata1==0x60000004) ( print "debug function check ok, ready to open" ;Writing SDA AP DBGENCTRL.GDBGEN and DBGENCTRL.CDBGEN data.set EDBG:&SDAP_DBGENCTRL %LE %Long 0x10000010 ) ELSE ( PRINT "debug function still closed, please check your security setting and password" ENDDO ) SYStem.Option TRST OFF SYStem.Option EnReset OFF SYStem.Option DUALPORT ON ; system.config debugporttype swd SYSTEM.JTAGclock 10Mhz SYSTEM.Attach print "debugger attached, but No flash driver" break ENDDO &arg1 to &arg8 fill in the real used key。 After saving, run the script using Lauderbach trace32, the results are as follows:  Fig 19  Fig 20  Fig 21 As you can see, Lauderbach can be unlocked and mounted, and can directly enter debug mode after downloading new code. 3.3 Segger JLINK unlock From the current situation, Segger JLINK's non-HSE static unlocking is relatively convenient, because the latest Segger driver has added this function by default, which can directly identify whether it is locked, and then ask for the key value to be entered, and it can be automatically unlocked after entering. The driver version supported by the test is: JLink_V812a, open the JLINK commander, and do the connection action:  Fig 22  Fig 23 As you can see, JLINK has been unlocked successfully. Of course, some lower-version drivers do not have this automatic lock recognition and require key input. In this case, you can unlock it by directly controlling the SDA_AP register. The following is my actual command line operation method and results, for reference only: J-Link>usb Disconnecting from J-Link...O.K. Disconnecting from J-Link...O.K. Connecting to J-Link via USB...O.K. Firmware: J-Link V11 compiled Dec 4 2024 17:53:35 Hardware version: V11.00 J-Link uptime (since boot): 0d 00h 00m 31s S/N: 601012430 License(s): RDI, FlashBP, FlashDL, JFlash, GDB USB speed mode: High speed (480 MBit/s) VTref=3.315V Device "S32K312" selected. Connecting to target via SWD ConfigTargetSettings() start ConfigTargetSettings() end - Took 15us InitTarget() start SDA_AP detected Unlocking device if necessary... Locked device detected. Proceeding with the unlock procedure... Locked S32K3xx device detected. For proper debugger connection the device needs to be unlocked via an password. Please specify the password via JLINK_ExecCommand() or by specifying a callback for an external dialog to enter the 16-byte password. InitTarget() end - Took 7.53s ConfigTargetSettings() start ConfigTargetSettings() end - Took 13us InitTarget() start SDA_AP detected Unlocking device if necessary... Locked device detected. Proceeding with the unlock procedure... Locked S32K3xx device detected. For proper debugger connection the device needs to be unlocked via an password. Please specify the password via JLINK_ExecCommand() or by specifying a callback for an external dialog to enter the 16-byte password. InitTarget() end - Took 1.96s Error occurred: Could not connect to the target device. For troubleshooting steps visit: https://wiki.segger.com/J-Link_Troubleshooting J-Link>WriteDP 2 0X070000FC Writing DP register 2 = 0x070000FC (0 write repetitions needed) J-Link>ReadAP 3 Reading AP register 3 = 0x001C0040 (0 read repetitions needed) J-Link>WriteDP 2 0X07000070 Writing DP register 2 = 0x07000070 (0 write repetitions needed) J-Link>ReadAP 0 Reading AP register 0 = 0x54030F33 (0 read repetitions needed) J-Link>ReadAP 1 Reading AP register 1 = 0x23100265 (0 read repetitions needed) J-Link>WriteDP 2 0x07000040 Writing DP register 2 = 0x07000040 (0 write repetitions needed) J-Link>WriteAP 0 0x03020100 Writing AP register 0 = 0x03020100 (0 write repetitions needed) J-Link>WriteAP 1 0X07060504 Writing AP register 1 = 0x07060504 (0 write repetitions needed) J-Link>WriteAP 2 0X11100908 Writing AP register 2 = 0x11100908 (0 write repetitions needed) J-Link>WriteAP 3 0X15141312 Writing AP register 3 = 0x15141312 (0 write repetitions needed) J-Link>WriteDP 2 0X07000050 Writing DP register 2 = 0x07000050 (0 write repetitions needed) J-Link>WriteAP 0 0X00000000 Writing AP register 0 = 0x00000000 (0 write repetitions needed) J-Link>WriteAP 1 0X00000000 Writing AP register 1 = 0x00000000 (0 write repetitions needed) J-Link>WriteAP 2 0X00000000 Writing AP register 2 = 0x00000000 (0 write repetitions needed) J-Link>WriteAP 3 0X00000000 Writing AP register 3 = 0x00000000 (0 write repetitions needed) J-Link>WriteDP 2 0X07000040 Writing DP register 2 = 0x07000040 (0 write repetitions needed) J-Link>ReadAP 0 Reading AP register 0 = 0x03020100 (0 read repetitions needed) J-Link>ReadAP 1 Reading AP register 1 = 0x07060504 (0 read repetitions needed) J-Link>ReadAP 2 Reading AP register 2 = 0x11100908 (0 read repetitions needed) J-Link>ReadAP 3 Reading AP register 3 = 0x15141312 (0 read repetitions needed) J-Link>WriteDP 2 0x07000000 Writing DP register 2 = 0x07000000 (0 write repetitions needed) J-Link>WriteAP 1 0X00000001 Writing AP register 1 = 0x00000001 (0 write repetitions needed) J-Link>WriteDP 2 0x07000000 Writing DP register 2 = 0x07000000 (0 write repetitions needed) J-Link>ReadAP 0 Reading AP register 0 = 0x60000004 (0 read repetitions needed) J-Link>connect Device "S32K312" selected. Connecting to target via SWD ConfigTargetSettings() start ConfigTargetSettings() end - Took 12us InitTarget() start SDA_AP detected Unlocking device if necessary... Device is not locked. Proceeding without the unlock procedure. Checking if debug access is already enabled... Debug access is not enabled yet. Performing enable debug access sequence... Debug access enabled Checking if HSE firmware is installed... HSE firmware not installed Checking if Cortex-M7_0 and Cortex-M7_1 are operating in lockstep mode Lock step mode disabled or not available InitTarget() end - Took 16.5ms Found SW-DP with ID 0x6BA02477 DPIDR: 0x6BA02477 CoreSight SoC-400 or earlier AP map detection skipped. Manually configured AP map found. AP[0]: MEM-AP (IDR: Not set, ADDR: 0x00000000) AP[1]: APB-AP (IDR: Not set, ADDR: 0x00000000) AP[2]: MEM-AP (IDR: Not set, ADDR: 0x00000000) AP[3]: AHB-AP (IDR: Not set, ADDR: 0x00000000) AP[4]: AHB-AP (IDR: Not set, ADDR: 0x00000000) AP[5]: AHB-AP (IDR: Not set, ADDR: 0x00000000) AP[6]: MEM-AP (IDR: Not set, ADDR: 0x00000000) AP[7]: MEM-AP (IDR: Not set, ADDR: 0x00000000) AP[4]: Skipped ROMBASE read. CoreBaseAddr manually set by user AP[4]: Core found CPUID register: 0x411FC272. Implementer code: 0x41 (ARM) Cache: L1 I/D-cache present Found Cortex-M7 r1p2, Little endian. FPUnit: 8 code (BP) slots and 0 literal slots ROM table scan skipped. CoreBaseAddr manually set by user: 0x40250400 I-Cache L1: 8 KB, 128 Sets, 32 Bytes/Line, 2-Way D-Cache L1: 8 KB, 64 Sets, 32 Bytes/Line, 4-Way SetupTarget() start Initializing ECC RAM... RAMCodeAddr: 0x20000000 RAMInitAddr: 0x20000010 RAMInitSize: 0x00007FF0 InitPattern: 0xDEADBEEF ECC RAM initialized successfully Initializing ECC RAM... RAMCodeAddr: 0x20000000 RAMInitAddr: 0x20400000 RAMInitSize: 0x00004000 InitPattern: 0xDEADBEEF ECC RAM initialized successfully SetupTarget() end - Took 12.0ms Memory zones: Zone: "Default" Description: Default access mode Cortex-M7 identified. J-Link> It should be noted here that for SDA_AP control, the addresses of the kernel and DAPBUS control are different, which is why the above command line controls the address starting from 0x07000000. It can be seen that the above command line method finally successfully injected the key and unlocked it successfully.   Fig 24   3.4 LC test result after unlock debug After unlocking, check the UTEST and DCM register values ​​of LC as follows:   Fig 25     Fig 26 As you can see, it is already in IN_FIELD. The values ​​in the UTEST area also meet the following conditions: LC slot1 is Inactive, LC slot2 is Inactive, LC slot3 is Active, LC slot4 is Erased, LC slot5 is Erased, 5. Sumarrize After the above detailed description, the static encryption of K312's non-HSE firmware is completed, and the use of different emulators: JLINK, PE Mulitlink, lauterbach for decryption is also implemented. Attachments: S32K312_C40_Ip_RTD400HF01_flash.zip: flash waiting operation S32K312_C40_Ip_RTD400HF01_flash_link.zip: link operation file to RAM S32K312_C40_Ip_RTD400HF01_flash_SJG.zip: secure debug encryption code S32K312_helloworld_RTD400HF01.zip: application test print helloworld code When doing this set of functions, I also encountered many pitfalls, which are summarized here. 5.1 Trap1:RTD400/500 flash operation copies to RAM   When a DFAE first reported this problem, I was still suspecting because after I copied the C40 code to RAM, I could still operate the flash successfully. But later I found that if I changed the erase area to block0, that is, when it was in the same block as the code, although the C40 code was copied to RAM successfully, and the map file was also in the ramcode area, when running it, it would go into hardfault and the error reported was still RWW error:       Fig 27 After many tests and final summary, we got the conclusion of Chapter 3.1. In fact, the code for processing C40 and OSIF was called without completing the flash operation, which led to the RWW problem. Therefore, after doing flash busy waiting or putting OSIF into RAM, the final test verification was successful. 5.2 Trap 2: Failure to push LC     After completing the key burning, the test of the flash value IN_FIELD of the LC area specified by IVT was OK, and then reset, even power on again, it can still enter the debug mode smoothly. This situation means that the secure debug is not successful at all. I was stuck at this point for eve one day, looking at the principles, registers, and memory. Finally, I was helpless and went back to the .s file to check the position of IVT. Only then did I find that the IVT and LC position of RTD400 were wrong, and it was actually written to the offset 0X28. After the modification, it was successful, and the emulator reminded that debug had been locked. This point of RTD500 has been fixed.     Fig 28 5.3 Trap 3: Lauterbach unlocking script fails to unlock This problem is also quite strange, because the same Lauterbach script was successfully unlocked by my colleagues and customers before, but it just couldn't be unlocked when I did it, and it was always locked. Later, After debug the Lauterbach script , we found that there were two points that were stuck, both about challenge is ready, but my chip was not challenge ready. Because this kind of static encryption does not need challenge at all, just take care of the response, so I skipped the challenge check directly later, such as blocking the following code: &rdata=Data.long(EDBG:&SDAP_AUTHSTTS)&0x00000001 while &rdata!=0x1 ( &rdata=Data.long(EDBG:&SDAP_AUTHSTTS)&0x00000001 ) Modify the script: &SDAP_AUTHSTTS_Read = Data.long(EDBG:&SDAP_AUTHSTTS) print "SDAP_AUTHSTTS is &SDAP_AUTHSTTS_Read" IF (&SDAP_AUTHSTTS_Read==0x60000005) ( print "debug function check ok, ready to open" ;Writing SDA AP DBGENCTRL.GDBGEN and DBGENCTRL.CDBGEN data.set EDBG:&SDAP_DBGENCTRL %LE %Long 0x10000010 ) To: &rdata1 = Data.long(EDBG:&SDAP_AUTHSTTS)&0x60000004 print "rdata1 is &rdata1" ;IF(&SDAP_AUTHSTTS_Read==0x60000005) IF (&rdata1==0x60000004) ( print "debug function check ok, ready to open" ;Writing SDA AP DBGENCTRL.GDBGEN and DBGENCTRL.CDBGEN data.set EDBG:&SDAP_DBGENCTRL %LE %Long 0x10000010 ) That is, the status register does not identify the challenge, and then unlock is working.
View full article
******************************************************************************** * Detailed Description: * Example is based on Siul2_Port_Ip_Example_S32K344 and its purpose it to show * how to integrate ITCM and DTCM memories to the project. * * Modification has been done in following files: * - main.c * - startup_cm7.s * - linker_flash_s32k344.ld * * In the main function, function is placed to ITCM memory and executed. Also * data field in placed to DCTM and accessed. * ******************************************************************************** * Test HW: S32K3X4EVB-Q172 * MCU: S32K344 * Compiler: S32DS3.4 * SDK release: PlatformSDK_S32K3_3_0_0 * Debugger: Lauterbach Trace32 ******************************************************************************** Revision History: Ver Date Author Description of Changes 0.1 Apr-04-2019 David Tosenovjan Initial version *******************************************************************************/
View full article
********************************************************************************  Detailed Description:  Example shows how to use FlexCAN 0 Pretended networking mode to allow FlexCAN  module to wake up MCU from STOP mode.  Wake up by Timeout and wake up by Match events are enabled.  Also pin interrupt can be used to exit STOP mode.  So MCU enters STOP mode by pressing SW3 button.  MCU exits STOP mode when one of following happens:  - no CAN message comes in 8sec (CAN PN timeout event)  - message with standard ID 0x554 or 0x555 comes (CAN PN match event)  - SW2 button is pressed (PTC12 interrupt)  In run mode blue LED is dimming and the rate is different for each wakeup event  ------------------------------------------------------------------------------  Test HW: S32K144 EVB-Q100  MCU: FS32K144UAVLL 0N57U  Fsys: 160MHz  Debugger: Lauterbach, OpenSDA  Target: internal_FLASH ********************************************************************************
View full article
Due to K3 hasn't been mass-produced yet, this content is moved to S32K3 Internal forum: https://community.nxp.com/t5/S32K3-Internal-Community/S32K3-Low-power-lab/ta-p/1280219 Any question, pls contact Jeremy.he@nxp.com.
View full article
Due to K3 hasn't been mass-produced yet, this content is moved to S32K3 Internal forum: https://community.nxp.com/t5/S32K3-Internal-Community/S32K3-Low-power-lab/ta-p/1280219 Any question, pls contact Jeremy.he@nxp.com.
View full article
*******************************************************************************  The purpose of this demo application is to present a usage of the  ADC_SAR and BCTU IP Driver for the S32K3xx MCU.  The example uses the PIT0 trigger to trigger BCTU conversion list to  perform  conversions on ADC1.  ADC channels  are selected to be converted on  ADC-1:  ADC1: P0, p1, p2, p3, p4, p5, p6, S10  Converted results from  BCTU_ADC_DATA_REG are moved by DMA into result array.  ADC channel S10 is connected to board's potentiometer.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ******************************************************************************** Set PIT Freeze Enable :--- All channels are for ADC-1 , in BCTU list :--     "NEW DATA DMA enable mask" :-- controls These bit field in MCR register     "ADC target mask" :-- It controls "ADC_SEL " bit field in "Trigger Configuration (TRGCFG_0 - TRGCFG_71)" for single conversions you can enable only one instance so the possible values for target mask: 1 (0b001) ADC0 2 (0b010) ADC1 3 (0b100) ADC2| for list of conversions we can enable also parallel con version for example 3 (0b011) parallel conversion of ADC0 and ADC1 The trigger is configured as a list of parallel conversions ADC0, ADC1 in “Adc Target Mask”. List of ADC channels is defined in “BCTU List Items” while order is given by the “Adc Target Mask”: BctuListItems_0 is ADC0, BctuListItems_1 is ADC1 etc.      
View full article
Hi everyone, Welcome to the NXP Tech Days 2024 training session AUT-T4977: Hands - On Workshop: S32K3 Ethernet- How to Configure Hardware and Software. This session was initially planned for 15 attendees. But due to the popularity of the lecture, we have increased the number of available seats . Therefore, we will work in pairs during the Hands-On. My name is Alejandro Flores Triana (Alex) and I will be your guide during this conference. I am an Automotive Applications Engineer supporting different OEMs, Tier1s, Partners and other internal NXP teams on topics related to communication protocols (e.g. CAN, LIN, SPI, I2C, Ethernet, etc.). The idea of this session is for you to understand how to program the S32K3 Ethernet interface using NXP Real-Time Drivers (RTDs) – Autosar MCAL Layer. We will use a base project and together modify it to create a simple Ethernet application. Therefore, to be ready follow the steps below to get your environment up and running before the session. On your laptop, install the NXP Software environment described in the attached presentation: Hands - On Workshop: S32K3 Ethernet Prerequisites.   Once you have the NXP software environment installed, download the attached project: S32K344_ETH_MCAL_TechDays.exe   Run the .exe project with administrator rights. Accept the license and install in the desired folder         Open the NXP Design Studio. Click File -> Import -> Existing Projects into Workspace   Select root directory and browse the folder where you downloaded the project   Select Copy projects into workspace   Click Finish. Select the project. Click on the arrow next to the hammer. Click on Debug_FLASH. Then you are ready for the session! See you soon. Best Regards, Alejandro Flores Triana
View full article
Hi,    Firstly, you should get the flash block size of your S32K3xx. Table in RM could be the reference.    Secondly, you should know that there are super sector and sector in S32K3xx.   Sector                    Subdivision of the Flash Block that is independently erasable. Sector Size is always 8 KB. Super sector          Subdivision of the flash block that includes a group of sectors. Super Sector Size is always 64 KB, and consists of 8 sectors.    Thirdly, based on the information of PFCBLKx_SSPELOCK in RM, you can calculate the numbers of super sector and sector in each flash block.   For example in S32K312, it has 2MB flash totally and each block is 1MB. So, in each 1MB, its first 768KB is with super sector granularity. The numbers of super sector is 768/64=12; the followed sector number is 256/8=32. Cheers! Oliver
View full article
Hi,     I would like to share with you the follow solution for S32K14x which could be attached while couldn't be re-programmed and stopped at RAM initializing.     If you met the issue as title, please check the SIM_CHIPCTL's value in IDE with attach function. Maybe you can find that the value is 0x0, which is not as default value after reset which is 0x0030_0000.     If you check the meaning on SIM_CHIPCTL, you can find that SRAMU and SRAML are retained across resets.  To solute the issue, you should add 'WRITE_LONG=00300000/40048004/ ;' in front of it the algorithm (it's better after reset) of freescale_s32k144f512m15_pflash_dflash_eeprom.arp which is at  'C:\NXP\S32DS_ARM_v20\eclipse\plugins\com.pemicro.debug.gdbjtag.pne_3.3.3.201712132114\win32\gdi\P&E\supportFiles_ARM\NXP\S32K1xx' After that, you can download your project as normal. Cheers! Oliver
View full article
******************************************************************************* The purpose of this demo application is to use pad keeping for  PINS and enter the standby mode & before entering the standby mode update variables in Standby RAM memory with pin state. Once wake up from the standby mode update the pins values from the STANDBY RAM variables.  S32K3xx MCU.  ------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: internal_FLASH ******************************************************************************** =============== How this DEMO works ========== Before entring standby :-- Before entering standby mode, i make BLUE LED high SW6 on board pressed to enter the standby mode. Wakeup from Standby :-- SW5 on board pressed to wakeup from standby After wakeup from Stand by:-- I glow Green LED Unglow the BLUE LED Wait for SW6 on board to be pressed to enter the standby mode. ===============  Stand by RAM location =============== As noted, the Standby SRAM is allocated at the first 32 KB of the SRAM Memory. https://www.mouser.com/pdfDocs/S32K3MemoriesGuide.pdf =============== Pins used for PAD keeping =============== PTA30, PTA31, PTD14     =============== Switches used ===============   Enter Standby mode, by pressing SW6 on Board EXIT Standby mode, by pressing SW5 on Board =============== Wakeup source, SW5 PTB26 =============== =============== WKPU[41]  ---> WKPU_CH_45=============== Because First 4 WKPU are timers, so 41 + 4 = 45   =============== Linker file changed =============== Added Standby RAM memory & sections for standby RAM memory. Changes can be seen by comparing the original linker file      =============== Startup file changed , startup_cm7.s =============== Added call to Initialise the Standby RAM Changes can be seen by comparing the original startup_cm7.s file     ======================= How to verify if Standby RAM is working =============== 1> Declare two variables in file Wkup.c :-- __attribute__ ((section (".standby_ram_data"))) volatile int test_0_value ; __attribute__ ((section (".standby_ram_data"))) volatile int test_1_value ;   2> function set_pin_value() will be called before entering the standby mode. Initialise the values to these two variables inside function set_pin_value() in file Wkup.c.   3> Now burn the code inside the MCU using the PE micro debugger.     Once code is burned do not run the code & disconnect the debugger. 4> Power OFF and power ON the S32K312 board. Now code is waiting to enter standby mode. Press switch SW6 MCU will enter standby mode & Blue LED glowing. Press switch SW5 MCU will wakeup from the standby mode. Code will Now code is waiting to enter standby mode 5> Now open your debugger configuration, and attach to running target.   6> Once connected click on the ELF file & press pause button.   7> In Debug window you can see the value of variables test_0_value & test_1_value same as initialised before entering the standby mode.      
View full article
******************************************************************************************************** Detailed Description: On WDOG timeout, the WDOG module requests reset in the Reset Control Module (RCM). The reset request to RCM can be delayed by 128 bus clock cycles if the WDOG interrupt is enabled (WDOG_CS[INT] = 1). If enabled, the WDOG interrupt vector is fetched or it becomes pending in NVIC. After the delay, the reset is requested in RCM. Independently of the WDOG interrupt, the RCM can again delay the reset by up to 514 LPO additional clock cycles if the corresponding RCM_WDOG interrupt is enabled (RCM_SRIE[GIE, WDOG] = 1). If so, instead of forcing reset immediately, the module requests the RCM interrupt in NVIC and forces the reset after the additional delay (RCM_SRIE[DELAY]). Either way, the reset is forced, it can’t be stopped only delayed. This example enables the WDOG interrupt in the WDOG_CS register but leaves this interrupt disabled in NVIC. That means that this interrupt becomes pending in NVIC on the WDOG timeout, it sets the WDOG_CS_FLG, but the vector doesn’t get fetched. The RCM interrupt is enabled and it gets asserted in NVIC after the WDOG interrupt delay (2.67us (48MHz BUS CLK)). The WDOG flag (WDOG_CS_FLG) is read in the RCM ISR instead. The execution stays in an infinite loop for 514 LPO (128kHz) cycles (~ 4ms) until the reset is forced. ------------------------------------------------------------------------------------------------------------------------- Test HW: S32K144EVB-Q100 MCU: S32K144 0N57U Debugger: S32DSR1 OpenSDA Target: internal_FLASH ********************************************************************************************************
View full article
******************************************************************************** * Detailed Description: * RAM self-test is performed after reset in startup_S32K144.s file. * The RAM self-test should be executed right after reset, so it does not destroy * data loaded to RAM by init functions. The code is inserted after * initialization of core registers. RAM initialization is commented out because * the same operation is done by the self-test. * The test flow is: * 1. Write pattern 0x55AA55AA to first word in RAM * 2. Read the data back * 3. Compare the data and increment error counter if not equal * 4. Write inverse pattern 0xAA55AA55 to first word in RAM * 5. Read the data back * 6. Compare the data and increment error counter if not equal * 7. Clear the first word in RAM to leave whole RAM erased to ‘0’ at the end of test * This procedure is repeated for whole RAM. * If the error counter is different from zero at the end, the program stays in * endless loop until watchdog reset. * * ------------------------------------------------------------------------------ * Test HW:         S32K144EVB-Q100 * MCU:             FS32K144UAVLL 0N57U * Fsys:            Default * Debugger:        Lauterbach Trace32 * Target:          internal_FLASH * ********************************************************************************
View full article
*******************************************************************************  The purpose of this demo application is to present a usage of the Bootloader Jump to Application.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ********************************************************************************   Jump is decided based on the boot_header, size we use to jump to the RESET handler:--   Cortex M-7 Interrupt vector table, RESET handler is 4 byte offset from starting of vector table :--   // Reset_Handler+1  --> required in IVT, to avoid hard fault As per Arm®v7-M Architecture Reference Manual  --> DDI0403E_e_armv7m_arm.pdf         How to burn elf file of both application & bootloader code :--  
View full article
[RTD400 LLD]K344 Center Aligned PWM Trigger ADC BCTU 1. Abstract     Not long ago, a customer's actual project needed to implement the high-level center point of the center-aligned PWM on the S32K3XX to trigger the ADC BCTU multi-channel sampling. This function requires the use of EMIOS, ADC, and BCTU. At the beginning, the customer was always unable to achieve the trigger at the center point of the PWM, and the trigger position was wrong. Later, After we give the explanation and analysis of the principles of the K3 related modules to the customer, as well as the guidance of the actual code configuration test, and the customer also achieved the required function. For the convenience of testing, PIT and UART printf functions are also added here. So here is a summary of the specific situation of this function, so that other customers who encounter similar functional requirements in the future can have a reference and can quickly build it. The requirements are as shown in the figure below. In the up-down counting mode, the center-aligned PWM is output, and the trigger sampling of the ADC BTCU LIST is realized at the center point of the high level. This article will implement 1KHZ center-aligned PWM, 50% duty cycle, and high-level center point to achieve ADC BTCU LIST sampling on the official S32K344-EVB board, based on the RTD400 LLD version.   Fig 1 2. Center-aligned PWM center point trigger ADC principle       Regarding the principle, there is no suspense about ADC. You can directly refer to the previous article on ADC software and hardware triggering: [RTD400 LLD]K344 ADC SW+HW trigger This is the structure shown in Figure 2. After configuring ADC, BCTU and select the triggered EMIOS channel. When the relevant flag of EMIOS is generated, BCTU will be triggered. After the watermark is reached, a notification will be generated to store all LIST ADC channel values ​​in the buffer, and then the ADC value can be printed out for easy viewing according to the situation.    Fig 2 In the current working condition, the logic that needs to be concerned about is mainly: how to generate center-aligned PWM, how to generate a flag at the high-level center point, and use this flag to trigger BTCU sampling. 2.1 How to generate center-aligned PWM      First, let’s take a look at the channel status of EMIOS and the channel status that supports center-aligned PWM.  Fig 3 The center-aligned PWM mode is: OPWMCB As shown in Figure 1, we can see that the counter count mode in this mode is up and down. Let's take a look at the channel types that support OPWMCB. We can see that there is only type G.   Fig 4 So, what are the channels supported by Type G? See the figure below:  Fig 5 The mystery is solved. Only CH1-CH7 of eMIOS supports center-aligned PWM. Well, then a new question arises. Can this mode directly generate a trigger signal at the center point of the PWM high level to trigger the ADC BCTU sampling? Answer: No! The reason can be seen from Figure 1. In this PWM mode, there are two trigger flags generated when the up and down count comparison is completed. Therefore, if this mode channel is used to directly trigger ADC sampling, two triggers will be generated in one cycle, and both are on the edge of PWM. Since OPWMCB cannot directly generate a trigger at the center point of PWM, how to achieve it? In addition, open a dedicated channel, and the clock source is the same as OPWMCB, but that channel only counts to generate trigger flags and does not output any waveform. 2.2 How to generate PWM center point trigger flag   Key information: OPWMCB simultaneous clock source, only counting mode, or up and down MCB mode, only one channel is satisfied: ADC CH0, counter bus type also needs to be selected as counter_bus_B       Fig 6 Let's take a look at the trigger flag of MCB:  Fig 7 As you can see, it is perfect. The trigger mark is at the top of the upward and downward counting, which is exactly the center point of the high level of the same source PWM. So, here, the specific channel arrangement has been determined in principle, two channels: EMIOS0_CH0 MCB mode pure counting and triggering the generation of flags to trigger ADC sampling; EMIOS0_CH1-CH7 is OPWMCB mode, simply outputting center-aligned PWM. 3. Software configuration and implementation       The software uses the S32K3 RTD400 version, and other versions have similar configurations! 3.1 Demo CT  module configuration First, you need to prepare a K344 demo, and then configure the pins, clocks, and peripheral modules. The following will explain the configurations. The modules used are: 2 GPIOs, ADC, BCTU, EMIOS clock, EMIOS PWM, LPUART for printing logs, PIT for timed printing, Trgmux is configured but not used in this article, so I won't talk about it!      3.1.1 Pin configuation       The pins used are as follows:  Fig 8 The two GPIOs are used to toggle in BCTU trigger notification and BCTU watermark notification respectively, to test the waveform positioning. ADC1_s10 pin is used for ADC1, but this article mainly uses BCTU to combine ADC0. ADC0 does not add specific external pins, but uses internal signals. LPUART is used for printing, and EMIOS0_CH1 is used to generate center-aligned PWM waveforms. 3.1.2 Clock configuration      The clocks that need to be paid attention to here are: ADC clock, EMIOS clock, UART clock, and PIT clock.  Fig 9 These clocks will be used later when configuring specific timing periods and baud rates. 3.1.3 Peripheral configuration       The peripherals used mainly include the following modules:  Fig 10 (1)Adc_Sar_Ip The configuration of the ADC0 module uses the one shot mode, that is, one conversion is generated after one trigger. In this way, the timer EMIOS channel can be used to generate trigger conditions to trigger a conversion. Pre-sampling is enabled to prevent the residual charge of the sampled value of the previous channel from affecting the result of the current channel and causing deviation of the ADC value. The trigger mode uses BCTU. For the configuration of Adc prescaler value and calibration prescale, the frequency division requirements in RM need to be met. The final configuration is as follows:  Fig 11    Fig 12 (2)Bctu_Ip The configuration of Bctu_Ip needs to select the right EMIOS channel to use. From the above principle, we can know that EMIOS0_CH0 is used, and then LIST mode is adopted. For ADC0, three internal channels are currently added to the LIST: BANDGAP, VREFL, VREFH. The specific configuration is as follows:  Fig 13   Fig 14 (3)Emios_Mcl_Ip Here we need to consider the PWM cycle that needs to be generated. The goal is to generate a 1Khz center-aligned PWM, so the EMIOS mode is the MCB up-down counting mode. The clock cycle formula for MCB is: (2 x AS1) – 2. So for the EMIOS0 clock source of 160Mhz, what is the corresponding 1KHZ counter? First do 160 divide to get 1Mhz, and then calculate according to (2 x AS1) – 2: (2 x AS1) – 2 = 1Mhz/1KHZ=>AS1=1000/2 +1= 501. The configuration is as follows:  Fig 15 (3)Emios_Pwm The previous principle analysis shows that the PWM uses the OPWMCB center-aligned mode PWM, the clock comes from the counter bus B of EMIOS CH0, then the period is 1khz, and the duty cycle is 50%. The specific configuration is as follows:  Fig 16 (4)Lpuart_Uart Configure UART6 clock baud rate to 115200.   Fig 17 (5)Pit   Fig 18 (6)IntCtrl_Ip The interrupt configuration is as follows, and it can actually be configured via code.  Fig 19 3.2 Main code situation After the configuration is completed, the output of the center PWM and the sampling of the ADC BCTU can be realized by calling the following code in main. #include "Clock_Ip.h" #include "IntCtrl_Ip.h" #include "Adc_Sar_Ip.h" #include "Bctu_Ip.h" #include "Siul2_Port_Ip.h" #include "Pit_Ip.h" #include "Siul2_Dio_Ip.h" #include "Trgmux_Ip.h" #include "Lpuart_Uart_Ip.h" #include "Lpuart_Uart_Ip_Irq.h" #include "string.h" #include "stdio.h" #include "retarget.h" #include "Emios_Mcl_Ip.h" #include "Emios_Pwm_Ip.h" /* PIT instance used - 0 */ #define PIT_INST_0 0U /* PIT Channel used - 0 */ #define CH_0 0U /* PIT time-out period - equivalent to 1s */ #define PIT_PERIOD 40000000 static volatile uint8 toggleLed = 0U; #ifdef ADC_3V3_VREF_SELECTED #define ADC_BANDGAP 5980U /* Vbandgap ~ 1.2V on 14 bits resolution, 3.3V VrefH */ #else #define ADC_BANDGAP 3932U /* Vbandgap ~ 1.2V on 14 bits resolution, 5V VrefH */ #endif #define ADC_SAR_USED_CH 48U /* Internal Bandgap Channel */ #define BCTU_USED_SINGLE_TRIG_IDX 0U #define BCTU_USED_FIFO_IDX 0U #define BCTU_FIFO_WATERMARK 3U #define ADC_TOLERANCE(x,y) (((x > y) ? (x - y) : (y - x)) > 200U) /* Check that the data is within tolerated range */ #define LED_Q172_PIN 13u #define LED_Q172_PORT PTA_H_HALF #define GPIO_PTA2_PIN 2u #define GPIO_PTA2_PORT PTA_L_HALF #define EMIOS_INST0 0U volatile int exit_code = 0; volatile boolean notif_triggered = FALSE; volatile boolean notif_triggered1 = FALSE; volatile uint16 data; volatile uint16 data1; volatile uint16 data_bctu[3]; #define UART_LPUART_INTERNAL_CHANNEL 6 #define WELCOME_MSG_1 "Hello, This message is sent via Uart!\r\n" volatile Lpuart_Uart_Ip_StatusType lpuartStatus = LPUART_UART_IP_STATUS_ERROR; uint32 remainingBytes; uint32 T_timeout = 0xFFFFFF; uint8* pBuffer; extern void Adc_Sar_0_Isr(void); extern void Bctu_0_Isr(void); extern void Adc_Sar_1_Isr(void); void AdcEndOfChainNotif(void) { notif_triggered = TRUE; data = Adc_Sar_Ip_GetConvData(ADCHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, ADC_SAR_USED_CH); /* Checks the measured ADC data conversion */ } void AdcEndOfChainNotif1(void) { notif_triggered1 = TRUE; data1 = Adc_Sar_Ip_GetConvData(ADCHWUNIT_1_BOARD_INITPERIPHERALS_INSTANCE, 34); /* Checks the measured ADC data conversion */ } void Pit0ch0Notification(void) { toggleLed = 1U; } void BctuWatermarkNotif(void) { uint8 idx; Siul2_Dio_Ip_WritePin(GPIO_PTA2_PORT, GPIO_PTA2_PIN, 1U); notif_triggered = TRUE; for (idx = 0u; idx < BCTU_FIFO_WATERMARK; idx++) { data_bctu[idx] = Bctu_Ip_GetFifoData(BCTUHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, BCTU_USED_FIFO_IDX); } Siul2_Dio_Ip_WritePin(GPIO_PTA2_PORT, GPIO_PTA2_PIN, 0U); } void BcutTriggerNotif() { Siul2_Dio_Ip_WritePin(LED_Q172_PORT, LED_Q172_PIN, 1U); Siul2_Dio_Ip_WritePin(LED_Q172_PORT, LED_Q172_PIN, 0U); } void TestDelay(uint32 delay); void TestDelay(uint32 delay) { static volatile uint32 DelayTimer = 0; while(DelayTimer < delay) { DelayTimer++; } DelayTimer = 0; } int main(void) { StatusType status; uint8 Index; Clock_Ip_StatusType clockStatus; /* Initialize and configure drivers */ clockStatus = Clock_Ip_Init(&Clock_Ip_aClockConfig[0]); while (clockStatus != CLOCK_IP_SUCCESS) { clockStatus = Clock_Ip_Init(&Clock_Ip_aClockConfig[0]); } Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS_PortContainer_0_BOARD_InitPeripherals, g_pin_mux_InitConfigArr_PortContainer_0_BOARD_InitPeripherals); #if 1 Bctu_Ip_Init(BCTUHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, &BctuHwUnit_0_BOARD_INITPERIPHERALS); status = (StatusType) Adc_Sar_Ip_Init(ADCHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, &AdcHwUnit_0_BOARD_InitPeripherals); while (status != E_OK); status = (StatusType) Adc_Sar_Ip_Init(ADCHWUNIT_1_BOARD_INITPERIPHERALS_INSTANCE, &AdcHwUnit_1_BOARD_InitPeripherals); while (status != E_OK); /* set PIT 0 interrupt */ IntCtrl_Ip_Init(&IntCtrlConfig_0); IntCtrl_Ip_EnableIrq(PIT0_IRQn); /* Install and enable interrupt handlers */ IntCtrl_Ip_InstallHandler(ADC0_IRQn, Adc_Sar_0_Isr, NULL_PTR); IntCtrl_Ip_InstallHandler(BCTU_IRQn, Bctu_0_Isr, NULL_PTR); IntCtrl_Ip_InstallHandler(ADC1_IRQn, Adc_Sar_1_Isr, NULL_PTR); IntCtrl_Ip_EnableIrq(ADC0_IRQn); IntCtrl_Ip_EnableIrq(BCTU_IRQn); IntCtrl_Ip_EnableIrq(ADC1_IRQn); // IntCtrl_Ip_EnableIrq(EMIOS0_5_IRQn); /* Call Calibration function multiple times, to mitigate instability of board source */ for(Index = 0; Index <= 5; Index++) { status = (StatusType) Adc_Sar_Ip_DoCalibration(ADCHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE); if(status == E_OK) { break; } } for(Index = 0; Index <= 5; Index++) { status = (StatusType) Adc_Sar_Ip_DoCalibration(ADCHWUNIT_1_BOARD_INITPERIPHERALS_INSTANCE); if(status == E_OK) { break; } } Adc_Sar_Ip_EnableNotifications(ADCHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN | ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN); Adc_Sar_Ip_EnableNotifications(ADCHWUNIT_1_BOARD_INITPERIPHERALS_INSTANCE, ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN | ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN); /* Start a SW triggered normal conversion on ADC_SAR */ Adc_Sar_Ip_StartConversion(ADCHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, ADC_SAR_IP_CONV_CHAIN_NORMAL); /* Wait for the notification to be triggered and read the data */ while (notif_triggered != TRUE); notif_triggered = FALSE; /* Start a SW triggered injected conversion on ADC_SAR */ Adc_Sar_Ip_StartConversion(ADCHWUNIT_0_BOARD_INITPERIPHERALS_INSTANCE, ADC_SAR_IP_CONV_CHAIN_INJECTED); /* Wait for the notification to be triggered and read the data */ while (notif_triggered != TRUE); notif_triggered = FALSE; #endif /* Initialize PIT instance 0 - Channel 0 */ Pit_Ip_Init(PIT_INST_0, &PIT_0_InitConfig_PB_BOARD_InitPeripherals); /* Initialize channel 0 */ Pit_Ip_InitChannel(PIT_INST_0, PIT_0_CH_0); /* Enable channel interrupt PIT_0 - CH_0 */ Pit_Ip_EnableChannelInterrupt(PIT_INST_0, CH_0); /* Start channel CH_0 */ Pit_Ip_StartChannel(PIT_INST_0, CH_0, PIT_PERIOD); // Trgmux_Ip_Init(&Trgmux_Ip_xTrgmuxInitPB);// Lpuart_Uart_Ip_Init(UART_LPUART_INTERNAL_CHANNEL, &Lpuart_Uart_Ip_xHwConfigPB_6_BOARD_INITPERIPHERALS); Emios_Mcl_Ip_Init(EMIOS_INST0, &Emios_Mcl_Ip_0_Config_BOARD_INITPERIPHERALS); Emios_Pwm_Ip_InitChannel(EMIOS_PWM_IP_BOARD_INITPERIPHERALS_I0_CH1_CFG, &Emios_Pwm_Ip_BOARD_InitPeripherals_I0_Ch1); printf("S32K344 PIT TRIGMUX ADC demo RTD400.\r\n"); /* Uart_AsyncSend transmit data */ lpuartStatus = Lpuart_Uart_Ip_AsyncSend(UART_LPUART_INTERNAL_CHANNEL, (const uint8 *) WELCOME_MSG_1, strlen(WELCOME_MSG_1)); /* Check for no on-going transmission */ do { lpuartStatus = Lpuart_Uart_Ip_GetTransmitStatus(UART_LPUART_INTERNAL_CHANNEL, &remainingBytes); } while (LPUART_UART_IP_STATUS_BUSY == lpuartStatus && 0 < T_timeout--); Siul2_Dio_Ip_WritePin(GPIO_PTA2_PORT, GPIO_PTA2_PIN, 0U); while(1) { #if 1 if( toggleLed == 1) { toggleLed = 0; printf("ADC0_bandgap ch48 data_bctu = %d .\r\n", data_bctu[0]); printf("ADC0_vrefl ch54 data_bctu = %d .\r\n", data_bctu[1]); printf("ADC0_vrefh ch55 data_bctu = %d .\r\n", data_bctu[2]); } #endif } return exit_code; } 3.3 Test result    The test results include two parts: the printed results show the ADC sampling value, and the relationship between the PWM output and the BCTU trigger position. The printed results are as follows, and you can see that the values ​​of the three different ADC channels are correct:  Fig 20 PWM wave test result is: Ch1:PTB13 PWM Ch2:PTA29 BCTU trigger notification Ch3: PTA2 BCTU watermark notification   Fig 21 From the figure, we can see that the first BCTU trigger is at the center point of the PWM high level, and the BCTU watermark notification is used to store data after the ADC sampling is triggered three times. Here is another waveform to view the PWM cycle:  Fig 22 It can be seen that the PWM period is 1Khz, the duty cycle is 50%, and the first trigger of BCTU is at the center of the PWM high pulse. 4. Summary and trip description Through the above configuration, the RTD400 LLD method was finally used on the S32K344-EVB to implement a 1Khz, 50% duty cycle center-aligned PWM, and the high pulse center position triggered the ADC BCTU LIST acquisition. The trip encountered were my own configuration problems. At the beginning, I mistakenly thought that the watermark configuration value was consistent with the number of LIST channels. In fact, the watermark trigger is triggered only when the watermark value is exceeded. Therefore, if it is a 3-channel LIST, the watermark needs to be configured as 2, not 3. If it is 3, the test waveform is as follows: Fig 23 As you can see, the watermark notification is actually generated after it is triggered 4 times. Therefore, remember to match the FIFO number of the watermark. Attachment: 1. S32K344_centerPWM1k_TRIGMUX_BCTUHWLIST_EMIOS_ADC_printf_RTD400.zip Center PWM triggered BCTU LIST   2.S32K344_CPWM1k_TRIGMUX_BCTUHWLIST_EMIOSch4_ADC_printf_RTD400.zip PWM emios0_ch4 falling edge trigger the BCTU, for the comment situation.   3. Another method of center trigger: MCB_Counter up. Emios0_CH0 as the counter bus EMIOS0_CH1 as the PWM output EMIOS0_CH2 as the center trigger, but no PWM output, OPWMB S32K344_NCPWM1k1_TRIGMUX_BCTUHWLIST_EMIOS_ADC_printf_RTD400.zip
View full article