S32K ナレッジベース

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

S32K Knowledge Base

ラベル

ディスカッション

ソート順:
S32K344 + MC33664 + MC33774 : RTD 3.0.0 : BMS SDK 1.0.2 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K344-MC33664-MC33774-RTD-3-0-0-BMS-SDK-1-0-2/ta-p/2028783 S32K344 + MC33665 + MC33774 : RTD 3.0.0 : BMS SDK 1.0.2 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K344-MC33665-MC33774-RTD-3-0-0-BMS-SDK-1-0-2/ta-p/2127108 S32K344 + MC33664 + MC33775 : RTD 3.0.0 : BMS SDK 1.0.2 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K344-MC33664-MC33775-RTD-3-0-0-BMS-SDK-1-0-2/ta-p/2127049 S32K344 + MC33665 + MC33775 : RTD 3.0.0 : BMS SDK 1.0.2 :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K344-MC33665-MC33775-RTD-3-0-0-BMS-SDK-1-0-2/ta-p/2127140 S32K144 : RTD-1.0.1 porting for : BCC_S32K144_FreeMASTER :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K144-RTD-1-0-1-porting-for-BCC-S32K144-FreeMASTER/ta-p/2130167
記事全体を表示
[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
記事全体を表示
[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.
記事全体を表示
This example code brief  :-- 1> Tested without the SL of BMS, so no dependency on the BMS Safety library. 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 :--      
記事全体を表示
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
記事全体を表示
******************************************************************************* The purpose of this demo application is to present a usage of the EMIOS IP Driver in Polling 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 IPWM mode .  :--       IPWM mode ,  ICU Driver User Manual :--   Result :--    ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ********************************************************************************
記事全体を表示
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
記事全体を表示
[S32K3 Tools Part] How to use VScode to compile EB MCAL project       For EB configured MCAL code, it is usually based on RTD and then compiled using the command line. When I first started learning, I always opened the relevant files directly to modify them, and then used the window cmd method to type commands. This method is very clumsy. Therefore, this article will show how to use VScode to open and compile a RTD4.0.0 S32K344 MCAL project. Of course, for MCAL EB projects, before compiling, you need to use the EB tool to open the configuration file of the corresponding project, and then close it after the project is generated. 1 VScode tool and configuration VScode download link: https://code.visualstudio.com/Download After downloading, install it. Here are some installation plug-ins I often use:   Fig 1 Fig 2 You can search in extensions and install it directly. 2. Use VScode to compile the RTD MCAL project This article takes RTD4.0.0, SW32K3_S32M27x_RTD_R21-11_4.0.0 as an example, and the platform is the official S32K344-EVB board. The code takes Dio_TS_T40D34M40I0R0 project as an example. In order not to affect the original routine, Dio_TS_T40D34M40I0R0 is copied and saved as Dio_TS_T40D34M40I0R0_vscode 2.1 Use EB tresos generate the configuration Open EB tools, import the project in path: C:\NXP\SW32K3_S32M27x_RTD_R21-11_4.0.0\eclipse\plugins\Dio_TS_T40D34M40I0R0_vscode\examples\EBT\S32K3XX\Dio_Example_S32K344\TresosProject Fig 3 Double-click someId, then right-click. If you do not need to make custom configurations, just click generate project. Wait for the generation to complete without errors and close the EB IDE. Fig 4 2.2 VScode  open project    First open VScode and select the project path in open Folder: C:\NXP\SW32K3_S32M27x_RTD_R21-11_4.0.0\eclipse\plugins\Dio_TS_T40D34M40I0R0_vscode\examples\EBT\S32K3XX\Dio_Example_S32K344 Fig 5 After opening, you can see that all the files in the path have been put in: Fig 6 You can save the workspace so you don't need to open the folder every time. File->Save workspace as, save to the path: C:\NXP\SW32K3_S32M27x_RTD_R21-11_4.0.0\eclipse\plugins\Dio_TS_T40D34M40I0R0_vscode\examples\EBT\S32K3XX\Dio_Example_S32K344   2.3 Modify mk file The project mk file needs to be modified to specify gcc, tresos paths, etc. Modify points:project_parameters.mk GCC_DIR = C:/NXP/S32DS.3.5_RTD400/S32DS/build_tools/gcc_v10.2/gcc-10.2-arm32-eabi TRESOS_DIR = C:/EB/tresos_29_0_0 PLUGINS_DIR = C:/NXP/SW32K3_S32M27x_RTD_R21-11_4.0.0/eclipse/plugins Fig 7 Modify points: check_build_params.mk Delete ifeq ("$(wildcard $(T32_DIR)/bin/windows/t32marm.exe)","") $(error Invalid path set to Trace32. \ The provided path: from project_parameters.mk T32_DIR=$(T32_DIR) is invalid!) Endif Fig 8 Then save all files:File->save all 2.4 Compile the file Terminal->New Terminal Enter the following command: >make generate >make build Fig 9 Fig 10 As you can see, after make build, an elf file has been generated in the out folder. This elf file can be directly downloaded using two methods: (1) S32DS empty project link to elf to download (2) Lauderbach directly download elf file   2.5 debug the generated elf file Since the S32K344-EVB has an onboard opensda tool, we directly use the S32DS empty project to link to the generated main.elf file to download and debug. Create a new S32DS project, and the interface is PE Multilink, then directly change the elf file to main.elf in the debug configuration, and then put the previously generated elf file into the folder of the new S32DS project:  \Debug_FLASH Fig 11 Then, enter debug mode, the results are as follows: Fig 12 As you can see, the chip has entered debug mode and can run successfully. Running at full speed, you can see the onboard red light flashing, so at this point, VSCode has compiled the MCAL code and run successfully.  
記事全体を表示
************************************************************************************************* * Detailed Description: * DCF record disables or enables POR_WDG depending on the POR_WDG_EN macro in main.c. * Find first available location in UTEST, by default, first available address is 0x1B000780 * * NOTE: There is a bug in this RTD version. * Change FLS_MAX_VIRTUAL_SECTOR to 272 in C40_Ip_Cfg.h * ------------------------------------------------------------------------------ * 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 : 3.0.0 * Build Version : S32K3_RTD_3_0_0_D2303_ASR_REL_4_7_REV_0000_20230331 *************************************************************************************************
記事全体を表示
*******************************************************************************  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 :--  
記事全体を表示
S32K344 - FOC integrated with FreeRTOS This example demonstrates a 3-phase Permanent Magnet Synchronous Motor (PMSM) vector control (Field Oriented Control - FOC) drive with 2- shunt current sensing with and without position sensor integrated in FreeRTOS environment. This design serves as an example of motor control design using NXP S32K3 automotive family. Example was designed on S32K344 Brushless Direct Current and Permanent Magnet Synchronous Motor Control Development Kit.  C-project based examples are part of MCSPTE1AK344 Development Kit Application Software. An innovative drivers set, Real-Time Drivers (RTD),are used to configure and control the MCU. It complies with Automotive-SPICE, ISO 26262, ISO 9001 and IATF 16949. Production-ready Automotive Math and Motor Control Library set provides essential building blocks for algorithm. FreeMASTER is used as useful run-time debugging tool. Application software contains:  MCSPTE1AK344_PMSM_FOC_2Sh_ll_FreeRTOS - Low-level drivers of RTD and S32 Design Studio Configuration Tools (S32CT) are used to demonstrate non-AUTOSAR approach. Since the motor control structure of the example is similar to dual shunt example, detailed description of the example can be found in application note AN13767 and FreeRTOS related part in AN12881 .
記事全体を表示
*******************************************************************************  The purpose of this demo application is to present a usage of the LPI2C-0 as MASTER and LPI2C-1 SLave, using DMA for TX & RX for the S32K3xx MCU.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ********************************************************************************
記事全体を表示
******************************************************************************* The purpose of this demo application is to place variables in DTCM memory for the S32K3xx MCU.  ------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE Micro * Target: internal_FLASH ******************************************************************************** ZERO table : is for bss segment variables :  contains RAM start & end address of BSS section which need to be initialized with ZER). Init_table : is for DATA segment variables : contains RAM start address of DATA section & START & end address of ROM address where the initialization values of the variables are stored.   Startup file startup_cm7.s call function init_data_bss() . Inside this function uses these section :-- Variables declared :-- Linker file changes :--   startup_cm7.s file changes :--   MAP file :--     Debug window results :--         https://www.kernel.org/doc/html/v5.9/arm/tcm.html   Due to being embedded inside the CPU, the TCM has a Harvard-architecture, so there is an ITCM (instruction TCM) and a DTCM (data TCM).  The DTCM can not contain any instructions, but the ITCM can actually contain data.   TCM is used for a few things: FIQ and other interrupt handlers that need deterministic timing and cannot wait for cache misses. Idle loops where all external RAM is set to self-refresh retention mode, so only on-chip RAM is accessible by the CPU and then we hang inside ITCM waiting for an interrupt. Other operations which implies shutting off or reconfiguring the external RAM controller.  
記事全体を表示
 ------------------------------------------------------------------------------ * 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 S32K31 SPI multiple packet Transmit & Receive : solution for DMA Cache issue :- https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K31-SPI-multiple-packet-Transmit-amp-Receive-solution/ta-p/2130091 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 S32K312 : HSE Demo project :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K312-HSE-Demo-project/ta-p/2112562 S32K312 : FS26 Watchdog trigger using the SBC_FS26 CDD :-- https://community.nxp.com/t5/S32K-Knowledge-Base/S32K312-FS26-Watchdog-trigger-using-the-SBC-FS26-CDD/ta-p/2161357
記事全体を表示
*******************************************************************************  The purpose of this demo application is to present a usage of the  FlexCAN IP Driver for the S32K3xx MCU.  The example uses FLEXCAN-0 for transmit & receive Tusing following Message buffer :-- #define RX_MB_IDX_0 10U #define RX_MB_IDX 11U #define TX_MB_IDX 12U FIFO Receive Message from range :-- 0x01 to 0x16 BAUDRATE : 500 KBPS  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ********************************************************************************    
記事全体を表示
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 length 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:  
記事全体を表示
******************************************************************************** * Detailed Description: * The example adds DTCM_1 backdoor access for CM7_0. * int_dtcm_1_bd memory region and section dtcm1_bd_data added to the linker file. * DTCM1 ECC initialized in startup_cm7.s * MPU on DTMC1 enabled in system.c * Global variables decleared with __attribute__ ((section(".dtcm1_bd_data"))) in main.c * ------------------------------------------------------------------------------ * Test HW: S32K314EVB-Q172 * MCU: S32K314 * Debugger: S32DS_ARM_3.4 * Target: internal_FLASH ********************************************************************************
記事全体を表示
What is “Flash Driver” (The following content is taken from Klaus Emmert->“FLASH Bootloader User Manual Version 2.7”) “The Flash Driver(actual flash algorithm) is the hardware dependent code for performing the flash functions.In most cases, programming flash memory from flash is not possible.Therefore the Flash Driver is downloaded and executed into RAM to allow programming of the application.The advantage of downloading the flash algorithm into RAM is that updates to the flash algorithms are possible without the need to reprogram the primary bootloader. The algorithm is cleared from RAM upon completion of the download to avoid accidental calls to the flash functions while in application. In special cases the flash algorithms are kept in flash memory and copied to RAM when needed. Of course the possibility of changing the flash algorithms is no longer available when this configuration is used. Moreover, there is a risk that the flash memory will be unintentionally erased from an accidental call to these functions. A remedy to correct this would be to encrypt the corresponding program code, such as e.g an XOR or the like.”   Regarding the demos -The software is using “S32 Design Studio for S32 Platform V3.4” and the SDK is “RTM 4.0.3” - Hardware based on S32K142-EVB -two demo provided, one for making “flash driver”, another is for testing the flash driver image     ·“Flash_Driver_Source_Project”  this routine used for making flash driver image.     ·“Flash_Driver_Source_Project_Test” this routine used for testing flash driver image.   ·Flash driver image making process 1.Create a new project and add the flash component       Refer to the demo provided and modified main.c file. Note 1 define function index table in main.c 2.Modify the link file Note 2 modified S32K142_32_flash.ld file   Note 3 modified S32K142_32_flash.ld file 3.Add “attribute” commands for the functions necessary to operate flash   Note 4 add "attribute" to function,like this         If another function is referenced in a function, then we also need to add “attribute” to the referenced function. 4.Compile the project and check the xx.map file to confirm whether the allocated address space is correct.   Note 5 check Flash_Driver_Source_Project.map 5.Make flash driver   Note 6 create flash image   Note 7 choose image format   Note 8 make flash driver image       New a “xx.s19” file and then copy the data which range of 0x1fffe000~0x1ffffffff into this file   Note 9 change link order if necessary       If some functions are distributed in different files, the function address allocated can be changed by changing the link order.   The process of testing the flash driver image 1.Create a new project without adding flash component.       You still need to create a new project, but you don’t need to add the Flash component to it. 2.Modify the link file as before. 3.Refer to the provided demo and modify main.c file. 4.Compile the project, check the .map file, and confirm whether the address space of the allocated array location is correct   Note 10 make sure Function_TABLE already put on the right place 5.Enter debug section, import the prepared flash driver image.   Note 12 import flash driver image before operate flash module 6.Test whether the flash driver can work normally.   Note 13 check the test result So far, we know how to make a flash driver image and how to test the flash driver image. This method is not limited to making functions related to flash operations, and other functions can also be used in this way, but there are few applications with such application scenarios.
記事全体を表示
************************************************************************************************ * Detailed Description: * The example shows how to skip an instruction * that causes uncorrectable ECC fault exception during C40_Ip_Read(). * ----------------------------------------------------------------------------------------------- * Test HW: S32312EVB-Q172 * MCU: S32K312 * Debugger: S32DS 3.4, PEMicro Multilink * Target: internal_FLASH *************************************************************************************************
記事全体を表示