S32K ナレッジベース

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

S32K Knowledge Base

ラベル

ディスカッション

ソート順:
[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.
記事全体を表示
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
記事全体を表示
This article provides a software package with additional example projects for wakeup use case using RTD 4.0.0 & 5.0.0. All the wakeup example projects mentioned in this page are developed based on RTD, with LLD or HLD.
記事全体を表示
  1. Abstract This article also explains the S32DS+EB configuration, RTD400. The MCAL training of other modules will be based on this structure in the future. However, this article will provide a command line version of the code. If you need the command line mode, you can directly copy one under the RTD MCAL code package and use VScode to compile it. The hardware of this article is based on K312-miniEVB, and the board situation is as follows:      Fig 1 Function: In the K312 MCAL code, the UART transceiver function is implemented using DMA. Since RTD400 does not have K312 routines, there is also a process of porting from RTD400 to K312 MCAL. Of course, the previous article has explained it very clearly, and also provided the S32DS project template. This article will be based on the previous S32DS EB project template.  2. Function Implementation 2.1 K312 MINIEVB hardware configuration For the hardware configuration, since this article only uses UART, the structure is very simple, using the pins: LPUART3_TX: PTD2 LPUART3_RX: PTD3 and an external TTL-USB tool to achieve signal communication. 2.2 EB Configuration     Here we list all the modules used in EB tresos related to this article, and focus on the modules that require specific configuration. Fig 2 2.2.1 Mcl module The Dma Logic Channel interface needs to be configured. The main purpose is to configure two DMA channels for LPUART3_TX and RX. (1)dmalogicChannel_Type_0 Fig 3 (2)dmalogicChannel_Type_2 Fig 4 The callback registered here can also be called directly in the code. 2.2.2 Mcu module Mcu->McuClockSettingConfig->McuClockReferencePoint->Lpuart3_clk Fig 5 In fact, it configures the clock source frequency of LPUART to 24Mhz, which comes from AIPS_SLOW_CLK. 2.2.3 Platform module Platform->Interrupt Controller->IntCtrlConfig,Configure 3 channels: Fig 6 Here we only need to pay attention to the LPUART3 interrupt, as well as the DMA0 channel 6 and channel 7 interrupts, because these two DMA channels are configured for UART TX and RX. FlexIO is ignored, it is just a matter of whether it is deleted in the original routine. 2.2.4 Port module Port->PortContainer, add PTD2,PTD3 pins: Fig 7 Fig 8 2.2.5 Uart module There are two places to configure: (1)uart->General Fig 9 (2)uart->uartChannel Fig 10 There are 4 points to note here: Point 1: Select the clock source configured in the mcu Point 2: Configure the baud rate to 115200 Point 3: Select the asynchronous mode as DMA Point 4: Select the two DMA channels configured in the mcl, and you need to match TX and RX to the corresponding DMA channels. 2.2.6 Rm module Rm->DMA MUX Configure 2 DMA_MUX channels: Fig 11 Fig 12 2.3 main code     #include "Mcl.h" #include "Mcu.h" #include "CDD_Uart.h" #include "CDD_Rm.h" #include "Port.h" #include "Platform.h" #include "Lpuart_Uart_Ip_Irq.h" #include "Flexio_Uart_Ip_Irq.h" //#include "check_example.h" #include <string.h> #include "Port_Cfg.h" #define UART_LPUART_INTERNAL_CHANNEL 0U #define UART_FLEXIO_TX_CHANNEL 1U #define UART_FLEXIO_RX_CHANNEL 2U /* Welcome messages displayed at the console */ #define WELCOME_MSG "MCAL UART DMA Helloworld for automotive with S32K312!\r\n" /* Error message displayed at the console, in case data is received erroneously */ #define ERROR_MSG "An error occurred! The application will stop!\r\n" /* Length of the message to be received from the console */ #define MSG_LEN 50U #define UART_BUFFER_LENGTH ((uint32)10U) Std_ReturnType T_Uart_Status; //uint8 Rx_Buffer[UART_BUFFER_LENGTH]; #define UART_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE #include "Uart_Memmap.h" __attribute__(( aligned(32) )) uint8 Rx_Buffer[UART_BUFFER_LENGTH]; #define UART_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE #include "Uart_Memmap.h" uint32 g_Uart_CallbackCounter = 0U; uint32 g_DmaCh16_ErrorCallbackCounter = 0U; uint32 g_DmaCh17_ErrorCallbackCounter = 0U; //void Uart_Callback (void); void Uart_Callback(const uint8 HwInstance, const Lpuart_Uart_Ip_EventType Event, void *UserData); void Mcl_DmaCh16_ErrorCallback (void); void Mcl_DmaCh17_ErrorCallback (void); void Uart_Callback(const uint8 HwInstance, const Lpuart_Uart_Ip_EventType Event, void *UserData) { if(Event == LPUART_UART_IP_EVENT_END_TRANSFER) { __asm volatile ("nop"); __asm volatile ("nop"); __asm volatile ("nop"); __asm volatile ("nop"); __asm volatile ("nop"); __asm volatile ("nop"); } else if (Event == LPUART_UART_IP_EVENT_TX_EMPTY) { __asm volatile ("nop"); __asm volatile ("nop"); } else if (Event == LPUART_UART_IP_EVENT_RX_FULL) { __asm volatile ("nop"); } else if (Event == LPUART_UART_IP_EVENT_ERROR) { __asm volatile ("nop"); } else { __asm volatile ("nop"); } } void Mcl_DmaCh6_ErrorCallback (void) { g_DmaCh16_ErrorCallbackCounter++; } void Mcl_DmaCh7_ErrorCallback (void) { g_DmaCh17_ErrorCallbackCounter++; } boolean User_Str_Cmp(const uint8 * pBuffer1, const uint8 * pBuffer2, const uint32 length) { uint32 idx = 0; for (idx = 0; idx < length; idx++) { if(pBuffer1[idx] != pBuffer2[idx]) { return FALSE; } } return TRUE; } /** * @brief Main function of the example * @details Initializez the used drivers and uses the Icu * and Dio drivers to toggle a LED on a push button */ int main(void) { Std_ReturnType UartStatus = E_NOT_OK; uint32 RemainingBytes; uint32 Timeout = 0xFFFFFF; Uart_StatusType UartReceiveStatus = UART_STATUS_TIMEOUT; Uart_StatusType UartTransmitStatus = UART_STATUS_TIMEOUT; /* Initialize the Mcu driver */ Mcu_Init(NULL_PTR); Mcu_InitClock(McuClockSettingConfig_0); Mcu_SetMode(McuModeSettingConf_0); /* Initialize Mcl module */ Mcl_Init(NULL_PTR); /* Initialize Rm driver for using DmaMux*/ Rm_Init (NULL_PTR); /* Initialize all pins using the Port driver */ Port_Init(NULL_PTR); /* Initialize IRQs */ Platform_Init(NULL_PTR); /* Initializes an UART driver*/ Uart_Init(NULL_PTR); T_Uart_Status = Uart_AsyncSend(UART_LPUART_INTERNAL_CHANNEL, (const uint8 *)WELCOME_MSG, strlen(WELCOME_MSG)); if (E_OK == T_Uart_Status) { do { /* Get transmission status */ UartTransmitStatus = Uart_GetStatus (UART_LPUART_INTERNAL_CHANNEL, &RemainingBytes, UART_SEND); } while (UART_STATUS_NO_ERROR != UartTransmitStatus && 0 < Timeout--); Timeout = 0xFFFFFF; UartTransmitStatus = UART_STATUS_TIMEOUT; } for(;;) { /* Receive data from the PC - Get 10 bytes in total */ UartStatus = Uart_AsyncReceive (UART_LPUART_INTERNAL_CHANNEL, Rx_Buffer, UART_BUFFER_LENGTH); if (E_OK == UartStatus) { do { /* Get receive status */ UartReceiveStatus = Uart_GetStatus (UART_LPUART_INTERNAL_CHANNEL, &RemainingBytes, UART_RECEIVE); } while (UART_STATUS_NO_ERROR != UartReceiveStatus && 0 < Timeout--); Timeout = 0xFFFFFF; UartReceiveStatus = UART_STATUS_TIMEOUT; } UartStatus = E_NOT_OK; /* Send data to the PC - Echo back the received data */ UartStatus = Uart_AsyncSend (UART_LPUART_INTERNAL_CHANNEL, Rx_Buffer, UART_BUFFER_LENGTH); if (E_OK == UartStatus) { do { /* Get transmission status */ UartTransmitStatus = Uart_GetStatus (UART_LPUART_INTERNAL_CHANNEL, &RemainingBytes, UART_SEND); } while (UART_STATUS_NO_ERROR != UartTransmitStatus && 0 < Timeout--); Timeout = 0xFFFFFF; UartTransmitStatus = UART_STATUS_TIMEOUT; } UartStatus = E_NOT_OK; } Uart_Deinit(); Mcl_DeInit(); // Exit_Example((T_Uart_Status1 == E_OK) && (T_Uart_Status2 == E_OK)); return (0U); }     It should be noted here that according to RTD C:\NXP\SW32K3_S32M27x_RTD_R21-11_4.0.0\eclipse\plugins\Uart_TS_T40D34M40I0R0\doc的RTD_UART_IM.pdf, RTD_UART_UM.pdf. Fig 13 When doing DMA transfer, the buffer needs to be placed in the noncacheable area. That's why this article is:     #define UART_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE #include "Uart_Memmap.h" __attribute__(( aligned(32) )) uint8 Rx_Buffer[UART_BUFFER_LENGTH]; #define UART_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE #include "Uart_Memmap.h"     3. Test Result Use UART3, pin UART3_TX:PTD2, UART3_RX:PTD3 After the chip is reset, send first: Helloworld for automotive with S32K344! Then wait for reception. After receiving 10 bytes of data, generate uart_callback interrupt and enter LPUART_UART_IP_ENET_END_TRANSFER. You can see that the data received in RX_Buffer is consistent with the data sent. Then, the code will loop back the received data. The test situation is as follows: The figure below shows two groups of tests: PC sends: 1234567890, after MCU receives it, loop it back. PC sends: 0987654321, after MCU receives it, debug stops at the breakpoint, you can check the received buffer situation, you can see that the buffer data is correct. Fig 14 Fig 15 Attached are two code packages: (1) Uart_TS_T40D34M40I0R0_miniK312_3.zipEB MCAL command line method After unzip the code, put it in: C:\NXP\SW32K3_S32M27x_RTD_R21-11_4.0.0\eclipse\plugins, and then you can compile it directly using the command line : Fig 16 (2)Mcal_UARTDMA_S32K312_RTD400_S32DS.zip:The way to import into S32DS, of course, it already contains the EB project: Fig 17 PS: Add another code, it add the IDLE function, based on the RTD400,  Mcal_UARTDMA_IDLE_S32K312_RTD400_S32DS.zip Test result is:      
記事全体を表示
     In fact, this topic has been written by many people before, and it is well written. However, in actual operation, you may encounter some pitfalls, so this article will not write the article steps in detail, but will provide a real and direct operation video process. The main reference article source link is: https://www.wpgdadatong.com.cn/blog/detail/74936 The method is very useful. I have tried the existing RTD4.0.0 MCAL code and also imported it into my own configured MCAL code. The method is reliable and effective. Platform:     SW32K3_S32M27x_RTD_R21-11_4.0.0 S32DS3.5 EB tresos Studio 29.0 S32K344-EVB Attach the video directly: The main steps are as follows: STEP 1. Create a new S32DS project STEP 2. S32DS project configuration Including folder deletion, addition, filter condition addition, include files, link files, optimization conditions, macro definitions, etc. STEP 3. Create a new EB project Configure a new RTD, or copy the existing RTD configuration to avoid unnecessary problems and errors. STEP 4. Compile and download The following are some related files that need to be copied: MCAL_Plugins->Link Source Resource Filters   Fig 1 Includes   Fig 2 "${ProjDirPath}/Generate/include" "${MCAL_PLUGIN_PATH}/Adc${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Ae${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/BaseNXP${MCAL_MODULE_NAME_SUFFIX}/header" "${MCAL_PLUGIN_PATH}/BaseNXP${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Can_43_FLEXCAN${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/CanIf${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/CanTrcv_43_AE${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Crc${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/CryIf${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Crypto_43_HSE${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Csm${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Dem${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Det${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Dio${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Dpga${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/EcuM${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Eth_43_GMAC${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/EthIf${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/EthSwt${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/EthTrcv${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Fee${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Gdu${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Gpt${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/I2c${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/I2s${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Icu${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Lin_43_LPUART_FLEXIO${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/LinIf${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/LinTrcv_43_AE${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Mcl${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Mcu${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Mem_43_EEP${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Mem_43_EXFLS${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Mem_43_INFLS${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/MemAcc${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/MemIf${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Ocotp${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Ocu${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Os${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Platform${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Platform${MCAL_MODULE_NAME_SUFFIX}/startup/include" "${MCAL_PLUGIN_PATH}/Port${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Pwm${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Rm${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Rte${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Sent${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Spi${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Uart${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Wdg${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/WdgIf${MCAL_MODULE_NAME_SUFFIX}/include" "${MCAL_PLUGIN_PATH}/Zipwire${MCAL_MODULE_NAME_SUFFIX}/include"   Preprocessor   Fig  3 S32K3XX S32K344 GCC USE_SW_VECTOR_MODE D_CACHE_ENABLE I_CACHE_ENABLE ENABLE_FPU   Linker   Fig  4 "${MCAL_PLUGIN_PATH}/Platform${MCAL_MODULE_NAME_SUFFIX}/build_files/gcc/linker_flash_s32k344.ld" optimization   Fig 5 -fno-short-enums -funsigned-char -fomit-frame-pointer -fstack-usage   main.c Comment: #include "check_example.h #Exit_Example(TRUE);    
記事全体を表示
 ------------------------------------------------------------------------------ * 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
記事全体を表示
*******************************************************************************  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 :--  
記事全体を表示
 ------------------------------------------------------------------------------ * 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 1U #define TX_MB_IDX 0U. BAUDRATE : 500 KBPS  ------------------------------------------------------------------------------ * 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 present a usage of the  ADC_SAR and BCTU IP Driver for the S32K3xx MCU.  The example uses the PIT0 trigger to trigger BCTU conversion list to  perform  conversions on ADC1.  ADC channels  are selected to be converted on  ADC-1:  ADC1: P0, p1, p2, p3, p4, p5, p6, S10  Converted results from  BCTU_ADC_DATA_REG are moved by DMA into result array.  ADC channel S10 is connected to board's potentiometer.  ------------------------------------------------------------------------------ * Test HW: S32K3X2EVB-Q172 * MCU: S32K312 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: PE micro * Target: internal_FLASH ******************************************************************************** Set PIT Freeze Enable :--- All channels are for ADC-1 , in BCTU list :--     "NEW DATA DMA enable mask" :-- controls These bit field in MCR register     "ADC target mask" :-- It controls "ADC_SEL " bit field in "Trigger Configuration (TRGCFG_0 - TRGCFG_71)" for single conversions you can enable only one instance so the possible values for target mask: 1 (0b001) ADC0 2 (0b010) ADC1 3 (0b100) ADC2| for list of conversions we can enable also parallel con version for example 3 (0b011) parallel conversion of ADC0 and ADC1 The trigger is configured as a list of parallel conversions ADC0, ADC1 in “Adc Target Mask”. List of ADC channels is defined in “BCTU List Items” while order is given by the “Adc Target Mask”: BctuListItems_0 is ADC0, BctuListItems_1 is ADC1 etc.      
記事全体を表示
*******************************************************************************  The purpose of this demo application is to present a usage of the  ADC_SAR and BCTU IP Driver for the S32K3xx MCU.  The example uses the PIT0 trigger to trigger BCTU conversion list to  perform parallel conversions on ADC0/ADC1. Three ADC channels  are selected to be converted on each ADC:  ADC0: S8 , P0, S8  ADC1: S10, S13, S17  Converted results from BCTU FIFO are moved by DMA into result array.  ADC channel S10 is connected to board's potentiometer, and converted value is  used to dim board's LED.  ------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K344 * Compiler: S32DS3.5 * SDK release: RTD 3.0.0 * Debugger: Lauterbach * Target: internal_FLASH ********************************************************************************
記事全体を表示
******************************************************************************** * 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 ********************************************************************************
記事全体を表示
************************************************************************************************ * 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 *************************************************************************************************
記事全体を表示
******************************************************************************** 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 - Callback function is used as well to handle TX and RX process in MBs and Enhanced RXFIFO - setupCanXCVR function can be called if TJA1153 is used on the board. It expects transceiver in Vanilla state and set TPL to pass all std and ext ID and do not block any message comming from bus. Finally leaving configuration mode without writing to non-volatile memory nor locking the transceiver. * * ------------------------------------------------------------------------------ * Test HW: S32K3444EVB-Q172 * MCU: PS32K344EHVPBS 1P55A * Compiler: S32DS.ARM.3.4 * SDK release: SW32K3_RTD_4_4_2_0_0_D2203 * Debugger: Lauterbach * Target: internal_FLASH * ********************************************************************************
記事全体を表示
Hi all, Recently, we completed S32K Sound Mixer reference code and demo, and glad to share this demo at here.   Some key feature of this demo:  - Demo HW based on S32K344/S32K148 + audio codec SGTL5000 + QSPI flash MX25L6433.  - Demo SW based on S32K3 RTD RTM 2.0.0 and S32K1 RTD RTM 1.0.0.  - Demo provided 2 kinds of sound mixing algorithm realization code, and corresponding audio materials and codec SGTL5000 driver.  - Demo showed how to programming QSPI flash and its AHB accessing via audio storage and playing process.  - Demo used mono audio as source for processing, and output stereo audio (I2S format) via SAI HW FIFO combine (Line_Mux) function with nearly no extra cost.   HMI/Cluster apps need multiple audio sources (usually warning sounds) be played simultaneously, which brings sound mixing ability requirement. However, S32K1/3 lack of this HW/SW feature support. With the demand from local key customer, and considering potential customer requirements, we planned to enable a SW sound mixer with scheduled peripherals, to enhance the S32K family audio mixing ability. It shall be easy of using/porting on S32K1/3, and use QSPI flash (AHB mode read) to store the music. Attachment the Sound Mixer package includes 2 sound mixing examples based on S32K344 EVB and S32K148 T-Box RDB, and some slides to introduce this implementation and quick start guide.    Thanks and welcome any comment from you. Best Regards, Shuailin Li
記事全体を表示
Symptoms Recently found the compatibility issue is a troublesome problem especially when we are supporting different version of RTD. Remove/install the RTD SDK and plug, but it is not a perfect way because reinstall the RTD would cause a lot of time, sometimes it is unreliable. Diagnosis After investigated the mechanism of CT and MEX file, and found a work around to let the old project can be run in new version of RTD basis. Solution Already tested it with several reference code and examples of RTD, it can work. Attached is the document.
記事全体を表示
Symptoms   Diagnosis   Solution  
記事全体を表示
******************************************************************************* * * The purpose of this demo application is to present a usage of the ADC_SAR and * BCTU IP Driver for the S32K3xx MCU. * * The example uses the PIT0 trigger to trigger BCTU conversion list. Five standard * ADC channels are selected to be converted. * Converted result from BCTU data register are moved by DMA into result array. * This result array should be placed into no cacheable area if data cache is enabled. * * ADC channel S10 is connected to board's potentiometer, and converted value is * used to dim board's LED. * * * ------------------------------------------------------------------------------ * Test HW: S32K3X4EVB-Q172 * MCU: S32K344 * Compiler: S32DS3.4 * SDK release: RTD 1.0.0 * Debugger: Lauterbach * Target: internal_FLASH ********************************************************************************
記事全体を表示