S32K Knowledge Base

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

S32K Knowledge Base

Labels

Discussions

Sort by:
[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
To restrict the S32K3 MCU access by JTAG the process depends on whether HSE FW is used or not. With HSE FW (not covered in this document): 1. Set up ADKP (Application Debug Key/Password). 2. Make sure the password mode or challenge-response mode. 3. Move the lifecycle to the IN-FIELD stage. NOTE: All the above steps can only be done via HSE services (not via IVT or by direct flash programming). Without HSE FW: WARNING: ONCE YOU REALIZE THIS PROCESS YOU CAN NOT CONFIGURE HSE IN THE DEVICE. NOTE: All the following codes represent just the essential part of the application and, where made using the S32K344 (not EVB), S32DS v3.5, the S32K3 Real-Time Drivers Version 3.0.0 (released on March 31, 2023) and a modified version of the C40_Ip_Example_S32K344, unless otherwise mentioned. As the debugger the PEmicro’s USB Multilink Universal FX was used, unless otherwise mentioned. 1. Program the field CUST_DB_PSWD_A: The UTEST Sector is an OTP (One Time Programmable). This causes the erase operations not to be allowed. You only going to be able to append new data or configuration and read data. This UTEST memory field is defined with a size of 32 bytes located from addresses 1B00_0080h to 1B00_009Fh, but its real size is 16 bytes because from 1B00_0090h to 1B00_009Fh is reserved (Table 184. UTEST memory location usage by SBAF of the S32K3xx Reference Manual, Rev. 7). To write the desired password in the UTEST Sector is the same process used to program data in other blocks. I. First, the sector needs to be unlocked to realize program operations. UTEST has its register PFCBLKU_SPELOCK[SLCK]. II. Once the sector is unlocked, write the 16-byte lend password at 1B00_0080h. The following changes need to be done in the example code: /*============================================================================ * LOCAL MACROS ============================================================================*/ #define FLS_MASTER_ID 0U #define FLS_BUF_SIZE 16U #define FLS_SECTOR_ADDR 0x1B000080U #define FLS_SECTOR_TEST C40_UTEST_ARRAY_0_S000 NOTE: Make sure that the definition FLS_MAX_VIRTUAL_SECTOR located in C40_Ip_Cfg.h has the same value as the C40_UTEST_ARRAY_0_S000 and that C40_SECTOR_ERROR is one value greater than C40_UTEST_ARRAY_0_S000.  For example instead of: #define FLS_MAX_VIRTUAL_SECTOR (527U) … #define C40_SECTOR_ERROR (528U) Needs to be: #define FLS_MAX_VIRTUAL_SECTOR (528U) … #define C40_SECTOR_ERROR (529U) /*============================================================================ * GLOBAL CONSTANTS ============================================================================*/ uint8 TxBuffer[FLS_BUF_SIZE] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}; /* Password */ You can confirm the password was written by using the Memory Viewer (not covered by this document).   2. Advance the MCU's lifecycle: I. First, set the address of the lifecycle configuration word in the IVT/boot header. For more information refer to sections 32.5 (Image vector table) and 32.5.3 (Structure definition of image vector table) of the S32K3xx Reference Manual, Rev. 7. NOTE: Make sure that the structure of the boot_header (located in Project_Settings -> Startup_Code -> startup_cm7.s) is defined as shown below:     #define LF_CONFIG_ADDR (0x007D2000) /* The LC word can be at any flash address, taking care that does not interfere with HSE */     II. Once defined LF_CONFIG_ADDR, write in such address the value for the LC word corresponding to the target lifecycle: Life cycle stage Valid Values for LC Advancement OEM_PROD DADA_DADAh IN_FIELD BABA_BABAh The following changes need to be done in the example code (the changes can be done in the same project used before):     /*=========================================================================== * LOCAL MACROS ===========================================================================*/ #define FLS_MASTER_ID 0U #define FLS_BUF_SIZE 8U #define FLS_SECTOR_ADDR 0x007D2000U #define FLS_SECTOR_TEST C40_CODE_ARRAY_0_BLOCK_3_S489 /* Look into C40_Ip_Cfg.h file to find the corresponding sector */ /*=========================================================================== * GLOBAL CONSTANTS ===========================================================================*/ uint8 LC_TxBuffer[FLS_LC_SIZE] = {0xDA, 0xDA, 0xDA, 0xDA, 0x0, 0x0, 0x0, 0x0}; /* Minimum data length 8 bytes */     Once the LC word is written in the memory, you can confirm the LC word was written by using the Memory viewer (not covered by this document). III. Reset the MCU NOTE: Directly from the reset pin (RESET_B), not the debugger. If the procedure was done correctly you should see the following message: Now to unlock the MCU, PEmicro provides some Python scripts (PEmicro support files package) to facilitate the authentication of the debugger when the password is set. In summary: I. Make sure to have already installed Python (3.5 or later). II. Open Command Prompt. III. Use cd to change the current working directory to where the file package is. IV. Run the script using: py authenticate_password_mode.py -hardwareid=USB1 -password=… Where hardwareid, is the debug hardware IP address, name, serial number, or port name. And the password is the preconfigured 16-byte hexadecimal. NOTE: This steps need to be done each time the MCU is reset or power cycled.  Once the debugger has been authenticated, you are going to be able to securely debug the device under S32DS. NOTE: Just make sure that In S32DS when you configure the Debug Configurations of a project, change the Target to the one that says "SECUREDEBUG". This is because during debug entry a hard reset is toggled which clears the authentication. You can follow the below steps for this:  
View full article
*********************************************************************************** * Detailed Description: * C40_Ip driver is moved to SRAM in files: C40_Ip.h, SchM_Mem_43_INFLS.h * The function that launches the C40_Ip APIs from main() is also placed in the SRAM. * Check the addresses of the APIs in the .map file. * ------------------------------------------------------------------------------ * Test HW: : S32K312EVB-Q172 * MCU: : S32K312 * Project : RTD AUTOSAR 4.7 * Platform : CORTEXM * Peripheral : S32K3XX * Dependencies : none * * Autosar Version : 4.7.0 * Autosar Revision : ASR_REL_4_7_REV_0000 * Autosar Conf.Variant : * SW Version : S32DS 3.5, RTD 5.0.0 * Build Version : S32K3_RTD_5_0_0_D2408_ASR_REL_4_7_REV_0000_20241002 ***********************************************************************************
View full article
******************************************************************************************** * Test HW: S32K312 EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: Internal_FLASH ******************************************************************************************** The objective of this demo application is to generate an interrupt by comparing DAC internal reference voltage against any analog input which is connected in analog mux input channels(IN0 : IN7) and wakes the MCU from sleep(standby) mode.  In this demo code,            1)LPCMP0 is used - DAC output is  given to comparator minus (INM) and                                                      AIN2 is given to comparator plus (INP).                From S32K3 RM, highlighted the channels used for reference.                                                                     Green color represents DAC, Pink color represents AIN2 which is selected from PMUX           2) From S32K RM,                "Compares two analog input voltages applied to INP and INM,                   COUT_RAW is high when the INP input voltage is greater than the INM input voltage,                   COUT_RAW is low when the INP input voltage is less than the INM input voltage"                So in this demo code,                RED LED is ON , if AIN2 Voltage > DAC Internal reference voltage(COUT is HIGH)                GREEN LED is ON, If AIN2 Voltage < DAC Internal reference voltage (COUT is LOW)   MODULES USED:   MODIFICATIONS IN LPCMP MODULE:       MODIFICATIONS IN INTCTRL_IP MODULE:     MODIFICATIONS IN WKPU MODULE:      From S32K3 RM, Analog comparator has used Channel 2 for wakeup.  Modifications in the "Cmp_Ip_IrqHandler" function in "Cmp_IP.c" source file: NOTE: Not sure how it got missed or from where to get COUT status, so added manually to get COUT status from CSR register in the Cmp_Ip_Irqhandler once code generation is completed.   PIN SELECTION DETAILS: HOW TO TEST?  a) Connect jumper wire at the PTC2 in the EVB as highlighted in EVB below. b) RED LED ON -> Jumper wire connects to 5V      GREEN LED ON-> Jumper wire connects to GND c) MCU enters STANDBY once SW5 is pressed and it wakes up if the jumper wire is disconnected from either 5V or GND. NOTE: In this demo, since jumper wire is used instead of button/ADC, due to high impendence state, LED will be toggling if jumper wire is not connected to GND/5V. Connect male jumper wire at PTC2 Thanks & regards, Krishnakumar V
View full article
******************************************************************************************** * Test HW: S32K312 EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: internal_FLASH ******************************************************************************************** The objective of this demo application is to generate an interrupt by comparing DAC internal reference voltage against any analog input which is connected in analog mux input channels(IN0 : IN7). In this demo code,            1)LPCMP0 is used - DAC output is  given to comparator minus (INM) and                                                      AIN2 is given to comparator plus (INP).                From S32K3 RM, highlighted the channels used for reference.                Green color represents DAC, Pink color represents AIN2 which is selected from PMUX          2) From S32K RM,                "Compares two analog input voltages applied to INP and INM,                   COUT_RAW is high when the INP input voltage is greater than the INM input voltage,                   COUT_RAW is low when the INP input voltage is less than the INM input voltage"                So in this demo code,                RED LED is ON , if AIN2 Voltage > DAC Internal reference voltage(COUT is HIGH)                GREEN LED is ON, If AIN2 Voltage < DAC Internal reference voltage (COUT is LOW)   Modules used:           Modifications in LPCMP module:   Modifications in IntCtrl_IP module: Modifications in the "Cmp_Ip_IrqHandler" function in "Cmp_IP.c" source file: Note: Not sure how it got missed or from where to get COUT status, so added manually to get COUT status from CSR register in the Cmp_Ip_Irqhandler once code generation is completed. GPIO selection details: How to test ? a) Connect jumper wire at the PTC2 in the EVB as highlighted in EVB below. b) RED LED ON -> Jumper wire connects to 5V      GREEN LED ON-> Jumper wire connects to GND Connect male jumper wire at PTC2 Thanks & regards, Krishnakumar V
View full article
*********************************************************************************** * Detailed Description: * The example locks * PFC PFCBLK2_SSPELOCK REG_PROT soft lock * and PFC REG_PROT hard lock. * ------------------------------------------------------------------------- * Test HW: : S32K344EVB-Q172 * MCU: : S32K344 * Project : RTD AUTOSAR 4.7 * Platform : CORTEXM * Peripheral : S32K3XX * Dependencies : none * * Autosar Version : 4.7.0 * Autosar Revision : ASR_REL_4_7_REV_0000 * SW Version : 5.0.0 * Build Version : S32K3_RTD_5_0_0_D2408_ASR_REL_4_7_REV_0000_20241002 ***********************************************************************************
View full article
This article has been moved to a new location: https://community.nxp.com/t5/S32M-Knowledge-Base/S32M2xx-Motor-control-use-cases/ta-p/2039790
View full article
 ------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: internal_FLASH ******************************************************************************** For S32K312, please use this correct clock HSE to AIPS clock should be ½. Please make these changes in the below all example code clock setting. HSE clock to 60 MHZ.   S32K312 PIT BTCU ADC-1 BCTU_ADC_DATA_REG DMA :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-PIT-BTCU-ADC-1-BCTU-ADC-DATA-REG-DMA-DS3-5/ta-p/1787778 S32K312 UART Transmit & Receive Using DMA :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-UART-Transmit-amp-Receive-Using-DMA-DS3-5-RTD300/ta-p/1787799 S32K312 EIRQ Interrupt :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-EIRQ-Interrupt-DS3-5-RTD300/ta-p/1787860 S32K312 SPI Transmit & Receive Using DMA :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-SPI-Transmit-amp-Receive-Using-DMA-DS3-5-RTD300/ta-p/1787856 Example S32K312 SPI Transmit & Receive Using Polling DS3.5 RTD300 :-- Example S32K312 SPI Transmit & Receive Using Polling DS3.5 RTD300 - NXP Community Example S32K312 SPI Transmit & Receive Using Interrupt DS3.5 RTD300 :-- Example S32K312 SPI Transmit & Receive Using Interrupt DS3.5 RTD300 - NXP Community S32K312 CAN Transmit & Receive Using Polling mode :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-CAN-Transmit-amp-Receive-Using-Polling-mode-DS3/ta-p/1789191 S32K312 CAN Transmit & Receive Using MB & FIFO DMA :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-CAN-Transmit-amp-Receive-Using-MB-amp-FIFO-DMA/ta-p/1789196 S32K312 ADC :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-ADC-DS3-5-RTD300/ta-p/1789282 S32K312 Switch Debouncing :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-Switch-Debouncing-DS3-5-RTD300/ta-p/1789290 S32K312 UART Freemaster :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-UART-Freemaster-DS3-5-RTD300/ta-p/1789306 S32K312 PIT BTCU parallel ADC FIFO DMA  :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-PIT-BTCU-parallel-ADC-FIFO-DMA-DS3-5-RTD300/ta-p/1789908 S32K312 placing variables in DCTM & code in ICTM  :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-placing-variables-in-DCTM-amp-code-in-ICTM-DS3-5/ta-p/1790101 Example S32K312 Standby mode & Standby RAM and PAD keeping DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-Standby-mode-amp-Standby-RAM-and-PAD-keeping-DS3/ta-p/1797713 Example S32K312 SWT DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-SWT-DS3-5-RTD300/ta-p/1800559 Example S32K312 Printf Semihosting DS3.5 RTD300 :--- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-Printf-Semihosting-DS3-5-RTD300/ta-p/1801354 Example S32K312 I2C Transmit & Receive Using DMA DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-I2C-Transmit-amp-Receive-Using-DMA-DS3-5-RTD300/ta-p/1801357 Example S32K312 HARDFAULT Handling Interrupt DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-HARDFAULT-Handling-Interrupt-DS3-5-RTD300/ta-p/1806259 Example S32K312 Bootloader to Application Jump DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-Bootloader-to-Application-Jump-DS3-5-RTD300/ta-p/1809810 Example S32K312 PIT timer Toggle LED DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-PIT-timer-Toggle-LED-DS3-5-RTD300/ta-p/1809932 Example S32K312 HARDFAULT Interrupt Handling using a script DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-HARDFAULT-Interrupt-Handling-using-a-script-DS3/ta-p/1818507 Example S32K312 UART Transmit & Receive Using Interrupt DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-UART-Transmit-amp-Receive-Using-Interrupt-DS3-5/ta-p/1818775 Example S32K312 CAN Transmit & Receive Using MB Interrupt DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-CAN-Transmit-amp-Receive-Using-MB-Interrupt-DS3/ta-p/1818790 Example S32K312 STANDBY wake up using CAN-0-RX and GPIO Switch DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-STANDBY-wake-up-using-CAN-0-RX-and-GPIO-Switch/ta-p/1891411 Example S32K312 STANDBY wake up using RTC DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-STANDBY-wake-up-using-RTC-DS3-5-RTD300/ta-p/1930115 S32K312 : ADC Clock selection :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K312-ADC-Clock-selection/ta-p/1997759 Example IP S32K312 PWM ICU using EMIOS Custom IRQ DS3.5 RTD300 :-- Example IP S32K312 PWM ICU using EMIOS DS3.5 RTD300 - NXP Community Example IP S32K312 EMIO PWM Generation & Duty capture using Interrupt DS3.5 RTD300 :-- Example IP S32K312 EMIO PWM Generation & Duty capture using Interrupt DS3.5 RTD300 - NXP Community Example IP S32K312 EMIO PWM Generation & Duty capture using Polling DS3.5 RTD300 :-- Example IP S32K312 EMIO PWM Generation & Duty capture using Polling DS3.5 RTD300 - NXP Community Example S32K312 Continuous SPI Transmit & Receive Using DMA DS3.5 RTD300 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K312-Continuous-SPI-Transmit-amp-Receive-Using-DMA/ta-p/2024597
View full article
This is an example project which is created to do an internal wake up from VLPS mode using LPTMR0.   From S32KRM, it tells us that internal wakeup is achievable using LPTMR0.     What code does? ======================================= 1) LPTMR0 is configured for 5 Seconds. So for interrupt occurs for every 5 seconds 2)LPTMR0  wakes up MCU for every 5 seconds and again it goes back to sleep for next 5 seconds. This cycle repeats forever. 3) When MCU is in RUN mode, GREEN color LED will be ON and it will in OFF if it goes to VLPS.   Project Configurations: =======================================     Other Informations: ======================================= Design studio: S32DS3.4 SDK                    : RTM 4.0.2 EVB                     : S32K118EVB2Q048   Note:   Following symbols should be included if you are creating the project from scratch to properly put MCU to sleep and wakeup from POR.   Thanks & regards, Krishnakumar V
View full article
【RTD400 MCAL 3】 K312 MCU clock system configuration 1. Abstract This document is talking about how to configure the clock system in the MCU of the K3 chip MCAL. This topic was always disdainful to talk about when I was doing LLD before, because the clock system of K3 is too simple, with internal fast and slow clock sources, external fast and slow clock sources, a PLL multiplier, and then various core peripherals to share. K3's RM even made a few options to frame the rules. From the perspective of LLD, especially the perspective of S32DS CT configuration, it is even more concise and clear. Here is a CT picture to show it:   Fig 1     Fig 2 With such a clock system, you can generate code with just a few taps and pokes. However, LLD is too free, and MCAL often encounters problems. Therefore, I decided to spend some time to understand the entire clock system of this MCAL MCU. This article takes K312 as an example to explain. Other K3 series are similar. 2. Clock system theory and configuration 2.1 K312 clock system From the clock chapter of RM, you can see the whole system block diagram:     Fig 3 This block diagram clearly shows the situation of each part. There are four clock sources: Internal fast clock FIRC: 48MHz, +/-5% error, maximum startup time 25us Internal slow clock SIRC: 32KHz, +/-10% error, maximum startup time 3ms External fast clock FXOSC: 8-40MHz, startup stabilization time FXOSC_CTRL[EOCV] × 128 External slow clock SXOSC: 32.768KHz, startup stabilization time SXOSC_CTRL[EOCV] x 128 One PLL: input 8-40MHZ, VOC output 640M-1280Mhz, PLL_PHIn_CLK output 25-480MHz. MUX_0: Output CORE_CLK, AIPS_PLAT_CLK, AIPS_SLOW_CLK, HSE_CLK, DCM_CLK MUX_1: Output system timer STM0_CLK MUX_3: Output FLEXCAN0-2 clock MUX_4: Output FLEXCAN3-5 clock MUX_5: Output CLKOUT_STANDBY MUX_6: Output CLKOUT_RUN MUX_11: Output TRACE_CLK RTC_CLK: RTC clock 2.1.1 PLL From the PLL perspective, we need to know which values ​​the frequency multiplier is related to, which can be calculated using the following formula:     Fig 4 If it is an integer, the red box in the above figure is the common method, and this article will also use the above method to configure. PLL_PHI is the clock output by the final PLL, which is provided to the MC corresponding to other MUXs for selection. 2.1.2 MUX_0 System The MUX_0 system with details can be seen from RM:     Fig 5 As you can see, the clock source of MUX_0 can be two types: PLL or internal FIRC. Then the core clock can be generated later, AIPS_PLAT_CLK, AIPS_SLOW_CLK, HSE_CLK, DCM_CLK. So what is the specific frequency of the generated clock? In principle, it can meet the maximum clock corresponding to each module, but the K3 series also makes some option recommendations. For example, K312 recommends using option B mode when RUN, especially the HSE clock, which usually needs to strictly meet the option recommendation. 2.1.3 MUX_6 Clock output In order to check the corresponding clock situation in the chip, the corresponding clock can be output through the CLKOUT pin. The CLKOUT pin can correspond to the selection of multiple clock sources. The specific situation is as follows:     Fig 6 The yellow content in the figure is what K312's CLKOUT_RUN can support. After the clock is configured, the corresponding clock will be selected to test whether the output is consistent with the configuration. 2.1.4 option B Recommended Solution In this article, K312 will configure the clock of option B in EB.     Fig 7 2.2 EB configuration        First, create a new K312 EB project. For the specific creation method, please refer to the previous article: [S32K3 Tools Part] How to port RTD's existing MCAL demo to other K3 chips This article will focus on the clock configuration corresponding to the MCU module based on RTD400 MCAL. For MCU configuration, two documents need to be consulted as reference books: C:\NXP\SW32K3_S32M27x_RTD_R21-11_4.0.0\eclipse\plugins\Mcu_TS_T40D34M40I0R0\doc: RTD_MCU_UM.pdf and RTD_MCU_IM.pdf If you don’t know how to configure, just follow the default values ​​recommended by the document. The following figure is an overview of the MCU. The main configured modules have the following three components: General, McuClockSettingConfig, McuModeSettingConf     Fig 8 2.2.1 General configuration In addition to Figure 8, you need to turn on the internal and external fast and slow clock control and PLL control, and add the corresponding API, as well as the crystal oscillator frequency. If this is not turned on, the corresponding configuration later will not be able to be configured.     Fig 9 2.2.2 McuClockSettingConfig configuration        This is the core area of ​​MCU clock configuration, which includes clock source, PLL, and various MUX conditions. First, you need to add a clock configuration:     Fig 10 Click in and there will be detailed configuration:     Fig 11 There are 17 items in total. You can keep the default configuration for options 1 and 6. Since the board does not connect to the external slow crystal oscillator 5, it is not configured. The rest should be configured according to the actual situation. The following explains them one by one: 2.2.2.1 McuFIRC configuration    Internal fast clock, 48MHz:     Fig 12 2.2.2.2 McuSIRC configuration Internal slow clock 32Khz     Fig 13 2.2.2.3 McuFXOSC configuration External crystal oscillator 16MHZ, fill in according to the actual connection situation.     Fig 14 2.2.2.4 McuCgm0ClockMux0 configuration Mux0 configuration, here are configured core clock, AIPS_PLAT_CLK, AIPS_SLOW_CLK, HSE, DCM_CLK, is to meet the optionB requirements, and the clock comes from PLL_PHI0_CLK. When actually configuring, first configure the PLL clock to output the correct PLL_PHI0_CLK, PLL_PHI1_CLK clock.     Fig 15 2.2.2.5 McuCgm0ClockMux1 configuration     Fig 16 It can be configured according to the clock source required by the actual module. 2.2.2.6 McuCgm0ClockMux3 configuration Configure the clock source of the FLEXCAN0-2 module:     Fig 17 2.2.2.7 McuCgm0ClockMux4 configuration Configure the clock source of the FLEXCAN3-5 module:     Fig 18 2.2.2.8 McuCgm0ClockMux5 configuration Configure the clock source of the CLKOUT_STANBY module:     Fig 19 2.2.2.9 McuCgm0ClockMux6 configuration Configure the clock source of the CLKOUT_RUN module     Fig 20 2.2.2.10 McuCgm0ClockMux11 configuration Configure the clock source of the TRACE_CLK module     Fig 21 2.2.2.11 McuRtcClockSelect configuration Configure the clock source of the RTC module     Fig 22 2.2.2.12 McuPLL configuration Configure the clock source of the PLL module     Fig 23 2.2.2.13 McuClockReferencePoint configuration Configure the reference clock and the clock source selection interface of the peripheral modules.     Fig 24 At this point, the clock configuration is complete. For verification, you can use the CLKOUT_RUN output to output the corresponding clock to pin PTD10 for viewing. 2.2.3 McuModeSettingConf  configuration In Mcu's McuModeSettingConf->McuPeripheral, you need to turn on the peripherals you want to use:     Fig 25 2.2.4 PORT  configuration Because the internal clock needs to be output to CLKOUT_RUN, K312's PTD10 MSCR106 is checked, so the PORT pin is added as follows:     Fig 26 3. Test Result Next, on the S32K312-EVB board, we modify the clock source of EB's CLKOUT_RUN to test whether the clock matches the configuration. Commonly used MCU-related drivers are as follows:     Fig 27 The calling sequence of system startup MCU initialization is as follows: 1). Mcu_Init() 2). Mcu_InitClock() 3). Mcu_GetPllStatus() - Till PLL is locked. 4). Mcu_DistributePllClock() 5). Mcu_SetMode() 6). Mcu_InitRamSection() - If required The corresponding main code is as follows: #include "Mcu.h" #include "Mcu_Cfg.h" #include "Port.h" #include "Dio.h" #include "Port_Cfg.h" #include "Platform.h" void TestDelay(uint32 delay); void TestDelay(uint32 delay) { static volatile uint32 DelayTimer = 0; while(DelayTimer < delay) { DelayTimer++; } DelayTimer = 0; } /** * @brief Main function of the example * @details Initialize the used drivers and uses the Icu * and Dio drivers to toggle a LED on a push button */ int main(void) { uint8 count = 0U; uint8 u8TimeOut = 100U; /* Initialize the Mcu driver */ #if (MCU_PRECOMPILE_SUPPORT == STD_ON) Mcu_Init(NULL_PTR); #elif (MCU_PRECOMPILE_SUPPORT == STD_OFF) Mcu_Init(&Mcu_Config_VS_0); #endif /* (MCU_PRECOMPILE_SUPPORT == STD_ON) */ /* Initialize the clock tree and apply PLL as system clock */ Mcu_InitClock(McuClockSettingConfig_0); #if (MCU_NO_PLL == STD_OFF) while ( MCU_PLL_LOCKED != Mcu_GetPllStatus() ) { } Mcu_DistributePllClock(); #endif /* Apply a mode configuration */ Mcu_SetMode(McuModeSettingConf_0); /* Initialize all pins using the Port driver */ Port_Init(NULL_PTR); /* Initialize Platform driver */ Platform_Init(NULL_PTR); while (count++ < 10) { Dio_WriteChannel(DioConf_DioChannel_Digital_Output_LED_Q172, STD_HIGH); Dio_WriteChannel(DioConf_DioChannel_Digital_Output_LED_Q257, STD_HIGH); TestDelay(5000000); Dio_WriteChannel(DioConf_DioChannel_Digital_Output_LED_Q172, STD_LOW); Dio_WriteChannel(DioConf_DioChannel_Digital_Output_LED_Q257, STD_LOW); TestDelay(5000000); } // Exit_Example(TRUE); return (0U); } #ifdef __cplusplus } #endif 3.1 CLKOUT FIRC_CLK DIV2     Fig 28 It can be seen that the original 48Mhz clock of FIRC is divided by 2 and the clock waveform of 24Mhz is obtained, which is correct! 3.2 CLKOUT SIRC_CLK DIV2     Fig 29 It can be seen that the original 32Khz clock of SIRC is divided by 2 and the clock waveform of 16khz is obtained, which is correct! 3.3 CLKOUT FXOSC_CLK DIV10     Fig 30 It can be seen that the original 16Mhz clock of FXOSC is divided by 10 and the clock waveform of 1.6Mhz is obtained. 3.4 CLKOUT PLLPH0 CLK DIV10     Fig 31 It can be seen that the original 120Mhz clock of PLLPH0 is divided by 10 and the 12Mhz clock waveform is obtained, which is correct. 3.5 CLKOUT CORE CLK DIV10     Fig 32 It can be seen that the original 120Mhz clock of CORE is divided by 10 and the 12Mhz clock waveform is obtained, which is correct. 3.6 CLKOUT PLLPH1 CLK DIV4     Fig 33 It can be seen that the original 48Mhz clock of PLLPH1 is divided by 4 and the 12Mhz clock waveform is obtained. 3.7 CLKOUT HSE CLK DIV10     Fig 34 It can be seen that the original 60Mhz clock of HSE is divided by 10 and the clock waveform of 6Mhz is obtained, which is correct. 3.8 CLKOUT AIPS_PLAT CLK DIV10     Fig 35 It can be seen that the original 60Mhz clock of AIPS_PLAT_CLK is divided by 10 and the clock waveform of 6Mhz is obtained, which is correct. 3.9 CLKOUT AIPS_SLOW CLK DIV10     Fig 36 It can be seen that the original 30Mhz clock of AIPS_SLOW_CLK is divided by 10 and the clock waveform of 3Mhz is obtained, which is correct.  
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
This example code brief  :-- 1> Tested without the SL of BMS, so no dependency on the BMS Saftey lbrary. 2> Its tested on 2 AFE MC33774 board connected in TPL 3> Change following macro in mc33774_cfg.h file  to change the numbers of AFE connected in TPL. RTD : 3.0.0 P07 BMS SDK : 1.0.2 This example does this task :-- Application Measurement. SYNC measurement Periodic Measurement. Read AFE temperature. Cell balancing timer method. Reading the Cell balancing status register & fault registers. =================== Setup used ============ Attached code is tested with TWO MC33774 AFE connected in TPL mode.         =============== MCU Pins used =========== TPL1-TX :-- TPL1TXCSB  --> PTC6/LPSPI0_PCS1 TPL1TXSCLK --> TPL12TXCLK --> PTE1/LPSPI0_SCK    TPL1TXDATA --> TPL12TXDATA --> PTE2/LPSPI0_SOUT    TPL1-RX :-- TPL1RXCSB  --> PTB17/LPSPI1_PCS3 TPL1RXCLK  --> PTB14/LPSPI1_SCK TPL1RXDATA --> PTB15/LPSPI1_SIN     ================= EVB Link ================== https://www.nxp.com/design/design-center/development-boards-and-designs/18-cell-battery-pack-emulator-to-supply-mc33774-bcc-evbs:BATT-18EMULATOR https://www.nxp.com/design/design-center/development-boards-and-designs/analog-toolbox/evaluation-board-for-mc33664atl-isolated-network-high-speed-transceiver:FRDMDUALK3664EVB https://www.nxp.com/design/design-center/development-boards-and-designs/mc33774ata-evaluation-board-with-isolated-daisy-chain-communication:RD33774ADSTEVB https://www.nxp.com/design/design-center/development-boards-and-designs/automotive-development-platforms/s32k-mcu-platforms/s32k3x4evb-t172-evaluation-board-for-automotive-general-purpose:S32K3X4EVB-T172   ================== Measurement types used in example ===== Periodic measurement is done by 33774 , this is cyclic Other Two : application , sync  need send command to start Application measurement , need send app_capture command twice , and then read the result. Synchronous measurement take out the Primary adc result(VC)and secondary result(VB) .But the VC and VB result comes from different adc. Period measurement start when you send  API "MSR_StartMeasurement" and then 774 will do period measurement automatically periodically :--   Why we need to measure Vc & Vb both :-- ASIL-D ,yes we can measurement VC channel by primary ADC and measurement VB by secondary ADC from hardware VC and VB are come from same point of battery cell. Now 2 ADC compare with each other, that lead to high safety (ASIL D). Primary & Secondary Device temperature reading :-- This API is used for it MC33774_CDD_BCC_SWC_Running_Slot4(). ============= Cell Balancing =========== Cell Balancing method used :-- MC33774 balance will switch between odd channel (1,3,5,7,... 17) and even channel (2,4,6,8,..18) by 500ms period , (250ms for odd and then switch to even 250ms and then odd 250ms...)it is because of IC design and cannot change by software.   MC33774 have lots of balance method  this example uses "timer method ". How to check Balancing is enabled :-- Following function MC33774_CDD_BCC_SWC_Running_Slot5() read the : Balance status & fault registers BAL_SWITCH_STAT0, BAL_SWITCH_STAT1 represent the balancing MOSFET current status.   Measure the voltage drop across the balancing register is the best approach. You will see the voltage drop appears every 250ms if PWM is 100%.  Please check the schematic of the 33774 EVB, find the balancing resistor on which channel balancing is enabled.     ======= How much time to wait to extract the measurements results ======= 240 us is the time of one SCAN Time between each Application measurement sequence. Min App measure time for 16 sample :-- 4.08ms = (16+1) *240 Min 1 SYNC measurement time, for 16 samples = 18 cycle ≈ 18 * (16*240us) ≈ 69 ms ============= Using Debugger ============ Debugger breakpoint will cause the communication timeout at the AFE, which will RESET the AFE. To use the debugger while development you need to disable the communication timeout. In S32DS MEX file you cannot disable the timeout function ( limit the value of 0~255) Disable Communication timeout in code :--   ================= Results for FIRST AFE =========================== Application Measurement : Cell voltage result :-- SYNC measurement : VC, VB same for both primary & Secondary  measure :--      
View full article
Hi team, First let me explain about the code about what it does. ======================================= 1) From POR, LED  starts blinking - In this state RTC won't be initialized. 2) Once SW5 is pressed in S32K312 EVB - RTC will be initialized before MCU goes to sleep. 3) RTCCNT will be incrementing during sleep  4) Once SW6 is pressed , MCU wakes from the sleep and we could able see the updated RTC time and date. WAR(Work Around)done to keep RTC alive during sleep: ======================================= Tried to test the RTC with sleep mode, observed that RTCCNT value is getting reset once after every wakeup. So that time and date was not able to preserve the value. In order to avoid this, I have done two workarounds to solve this RTCCNT value reset issue. 1) RTC will not be initialized for if MCU wakeup from the sleep - Made the check to initialize when MCU is not from the wakeup before it goes to sleep. wake_up_event will be incremented if MCU reset reason is wakeup as shown below.   2) Updating "Rtc_Ip_u32ChState" array variable for "ticksPerSecond" member in "Rtc_Ip.c" file manually after the code generation is completed.  Note: With auto generated code the value of "ticksPerSecond "will be "0".    Any other alternatives other than this approach is highly appreciated. Thanks in advance!  
View full article
*******************************************************************************  The purpose of this demo application is to present a usage of the  LPSPI IP Driver for the S32K3xx MCU.  The example uses LPSPI2 for transmit & receive Twelve bytes using the DMA. This above mentioned operation is performed 10 times continuously MOSI MISO connected on Hardware in loopback.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ******************************************************************************** For S32K312, please use this correct clock HSE to AIPS clock should be ½. Please make these changes in the below all example code clock setting. HSE clock to 60 MHZ.     Use this MACRO to enable disable the non cacheable region variable placement :--          
View full article
******************************************************************************************** * Test HW: S32K311 EVB-Q100 * MCU: S32K311 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: internal_FLASH ******************************************************************************************** The purpose of this demo application is to enter the standby mode and waking up from sleep using the user button. =============== How this DEMO works ========== 1) once the image is flashed, the application starts running and BLUE LED blinks for every one second during RUN mode 2) Once SW5 in EVB is pressed, MCU enters the SLEEP mode and it turns off BLUE LED & PIT 3) To Wakeup: Press SW4 in EVB 4) Once it returns to normal mode, BLUE LED and PIT starts running. Used pins: ========= PTC11 -> SW5 -> EnterStandby PTA8 -> SW4 -> WakeupFromSleep PTB8 -> D12   -> Blue led  
View full article
The purpose of this demo application is to show you the usage of the FlexCAN module configured to use CAN FD and Enhance RXFIFO using the S32 RTD API. - This demo application requires two boards, or single board connected with CAN tool. - CAN FD is enabled with bitrate 500/2000 kbps - MB0 is configured to transmit either std. or ext ID - MB1 is configured to receive ext ID 0xFACE and MB2 to receive std ID 0x1 - Enhanced RXFIFO is enabled and 3 enhanced RXFIFO filter elements (filter + mask scheme) are defined ext ID 0xABCD with mask 0x1FFFFFFF std ID 0x123 with mask 0x7FF std ID 0x456 with mask 0x7FF - DMA is used to read enhanced RXFIFO, watermark is set to 5 - Callback function is used as well to handle TX and RX process in MBs and Enhanced RXFIFO after DMA complete 5 reading of RXFIFO  ------------------------------------------------------------------------------  Test HW: S32K3444EVB-Q172  MCU: PS32K344EHVPBS 1P55A  Compiler: S32DS.ARM.3.5  SDK release: S32K3_RTD_4_0_0_D2311  Debugger: Lauterbach  Target: internal_FLASH
View full article
*******************************************************************************  The purpose of this demo application is to present a usage of the  LPSPI IP Driver for the S32K3xx MCU.  The example uses LPSPI2 for transmit & receive Twelve bytes using the SPI Interrupt Lpspi_Ip_AsyncTransmit() method . MOSI MISO connected on Hardware in loopback.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ******************************************************************************** Interrupt Triggered :-- Async callback triggered at the end of transfer/reception :-- Lpspi_Ip_AsyncTransmit(&MASTER_EXTERNAL_DEVICE, txBuffer, rxBuffer, numberOfBytes, lpspi_callback_int);      
View full article
*******************************************************************************  The purpose of this demo application is to present a usage of the  LPSPI IP Driver for the S32K3xx MCU.  The example uses LPSPI2 for transmit & receive Twelve bytes using the SPI polling Lpspi_Ip_SyncTransmit() method. MOSI MISO connected on Hardware in loopback.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ********************************************************************************    
View full article
 ------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: internal_FLASH ******************************************************************************** Example MCAL S32K312 MEM_InFls  DS3.5 RTD300 :-- Example MCAL S32K312 MEM_InFls DS3.5 RTD300 - NXP Community Example MCAL S32K312 FEE DS3.5 RTD300 :-- Example MCAL S32K312 FEE DS3.5 RTD300 - NXP Community Example MCAL S32K312 FEE and MEM_InFls DS3.5 RTD300 :-- Example MCAL S32K312 FEE and MEM_InFls DS3.5 RTD300 - NXP Community Example MCAL S32K312 PWM ICU using Custom IRQ EMIOS DS3.5 RTD300 :-- Example MCAL S32K312 PWM ICU using EMIOS DS3.5 RTD300 - NXP Community Example ASR S32K312 EMIO PWM Generation & Duty capture using Interrupt DS3.5 RTD300 :-- Example ASR S32K312 EMIO PWM Generation & Duty capture using Interrupt DS3.5 RTD300 - NXP Community  Example ASR S32K312 EMIO PWM Generation & Duty capture using Polling DS3.5 RTD300 :-- Example ASR S32K312 EMIO PWM Generation & Duty capture using Polling DS3.5 RTD300 - NXP Community
View full article
******************************************************************************* The purpose of this demo application is to present a usage of the EMIOS IP Driver in Interrupt mode for the S32K3xx MCU. The example use to :-- EMIOS-1 - ch-0  --> PTC24 --> Generate the PWM EMIOS-1 - ch-1  --> PTC25 --> is the ICU channel to measure the duty Pins used :--     This example is tested for SAIC & IPWM mode both. You can change the mode by this setting in MEX file :--     Difference between SAIC & IPWM,  ICU Driver User Manual :--   These Two Macro :-- SAIC_MODE  --> this maco will enable variables to store for SAIC mode CUSTOM_IRQ  --> this MACRO will enable customized IRQ or RTD available IRQ   Result :--     Sometimes Compiling error comes, in Autogenerated RTD file.    Change the Header file name :--    ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ********************************************************************************
View full article