hi, I enable an interrupt of 100us per cycle. Then I erase one sector of data flash.
I called an API function called "C40_Ip_MainInterfaceSectorErase" to erase data flash
During erasure, interrupts cannot be responded to.
After erasure, interrupts can be responded to normally.
I use the chip of S32K312.
So, how to achieve the goal to enter interrupts while erasing data flash?
Looking forward to your reply
Solved! Go to Solution.
For convenience, I modified some of your code. You can copy it directly into your project and observe the Counter variable through the debugger. I didn't find any problems.
/*
* (c) Copyright 2022 NXP
*
* NXP Confidential. This software is owned or controlled by NXP and may only be used strictly
* in accordance with the applicable license terms. By expressly accepting
* such terms or by downloading, installing, activating and/or otherwise using
* the software, you are agreeing that you have read, and that you agree to
* comply with and are bound by, such license terms. If you do not agree to
* be bound by the applicable license terms, then you may not retain,
* install, activate or otherwise use the software.
*
* This file contains sample code only. It is not part of the production code deliverables.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*==================================================================================================
* INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Clock_Ip.h"
#include "C40_Ip.h"
#include "Pit_Ip.h"
#include "check_example.h"
#include "IntCtrl_Ip.h"
#include "OsIf.h"
#include "String.h"
/*==================================================================================================
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/
/*==================================================================================================
* LOCAL MACROS
==================================================================================================*/
#define FLS_MASTER_ID 0U
#define FLS_BUF_SIZE 1024U
#define FLS_SECTOR_ADDR 0x10000000U
#define FLS_SECTOR_TEST C40_DATA_ARRAY_0_BLOCK_2_S000
#define PIT0_INST 0
#define PIT0_CH0 0
#define PIT1_INST 1
#define PIT1_CH1 1
/*==================================================================================================
* LOCAL CONSTANTS
==================================================================================================*/
/*==================================================================================================
* LOCAL VARIABLES
==================================================================================================*/
/*==================================================================================================
* GLOBAL CONSTANTS
==================================================================================================*/
uint8 TxBuffer[FLS_BUF_SIZE];
uint8 RxBuffer[FLS_BUF_SIZE];
uint32 write_start_time = 0;
uint32 write_end_time = 0;
uint32 write_duration_time = 0;
uint32 erase_start_time = 0;
uint32 erase_end_time = 0;
uint32 erase_duration_time = 0;
uint32 Interrupt_scheduling_cycle = 0;
uint32 current_time = 0;
uint32 last_time = 0;
uint32 test = 0;
uint32 Counter = 0;
/*==================================================================================================
* GLOBAL VARIABLES
==================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTION PROTOTYPES
==================================================================================================*/
void Fls_InitBuffers(void);
void Fls_ExampleAssert(boolean Condition);
/* External functions and variables */
extern ISR(PIT_1_ISR);
/*==================================================================================================
* LOCAL FUNCTIONS
==================================================================================================*/
/**
* @brief Implement a simple assert macro
*
* @Param Condition
* @return void
*/
void Fls_ExampleAssert(boolean Condition)
{
while (!Condition)
{
/* Loop forever */
}
}
void Fls_InitBuffers(void)
{
uint32 Index;
for (Index = 0U; Index < FLS_BUF_SIZE; Index++)
{
TxBuffer[Index] = (uint8)0xaa;
RxBuffer[Index] = 0U;
}
}
C40_Ip_StatusType __attribute__((section (".ramcode"))) Fls_WriteSector(volatile uint32 u32LogicalAddress, uint32 u32Length,const uint8 *pSourceAddressPtr, uint8 u8DomainIdValue)
{
C40_Ip_StatusType C40_Ip_Status = STATUS_C40_IP_ERROR ;
uint32_t writeLen = 0u ;
while (u32Length > 0)
{
if(u32Length > 128)
{
writeLen = 128 ;
}
else
{
writeLen = u32Length ;
}
/* Write data */
C40_Ip_Status = C40_Ip_MainInterfaceWrite(u32LogicalAddress,writeLen,(const uint8_t*) pSourceAddressPtr, u8DomainIdValue);
do
{
C40_Ip_Status = C40_Ip_MainInterfaceWriteStatus();
} while (STATUS_C40_IP_BUSY == C40_Ip_Status);
u32LogicalAddress += writeLen;
pSourceAddressPtr += writeLen;
u32Length -= writeLen;
}
return C40_Ip_Status ;
}
C40_Ip_StatusType __attribute__((section (".ramcode"))) Fls_EraseSector(C40_Ip_VirtualSectorsType Fls_VirtualSector,uint8 u8DomainIdValue)
{
C40_Ip_StatusType C40_Ip_Status = STATUS_C40_IP_ERROR ;
/* Erase sector */
C40_Ip_MainInterfaceSectorErase(Fls_VirtualSector, u8DomainIdValue);
do
{
C40_Ip_Status = C40_Ip_MainInterfaceSectorEraseStatus();
}
while (STATUS_C40_IP_BUSY == C40_Ip_Status);
return C40_Ip_Status ;
}
/* Callback functions definition */
void Pit1_Ch1_Callback (uint8 channel)
{
(void)channel;
Counter++;
}
/*==================================================================================================
* GLOBAL FUNCTIONS
==================================================================================================*/
/**
* @brief Main function of the example
* @details Initializes IP C40 driver and erase, write, read internal flash memory
*/
void main(void)
{
uint32 Index;
C40_Ip_StatusType C40Status;
Clock_Ip_StatusType ClockStatus;
/* Initialize clock */
ClockStatus = Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);
Fls_ExampleAssert(ClockStatus == CLOCK_IP_SUCCESS);
/* OsIf initialization */
OsIf_Init(NULL);
/* Initialize C40 driver */
C40Status = C40_Ip_Init(&C40ConfigSet_VS_0_InitCfg);
Fls_ExampleAssert(STATUS_C40_IP_SUCCESS == C40Status);
/* Initialize buffers */
Fls_InitBuffers();
/* PIT timer and interrupt configuration */
Pit_Ip_Init(PIT0_INST, &PIT_0_InitConfig_PB);
Pit_Ip_Init(PIT1_INST, &PIT_1_InitConfig_PB);
Pit_Ip_InitChannel(PIT0_INST, &PIT_0_ChannelConfig_PB[0]);
Pit_Ip_InitChannel(PIT1_INST, &PIT_1_ChannelConfig_PB[0]);
/* PIT0_CH0 period is 100mS since its clock is AIPS_SLOW_CLK 40MHz */
Pit_Ip_StartChannel(PIT0_INST, PIT0_CH0, 4000000);
Pit_Ip_StartChannel(PIT1_INST, PIT1_CH1, 400); //10us interrupt
Pit_Ip_EnableChannelInterrupt(PIT1_INST, PIT1_CH1);
/* Install IRQ handler for PIT0 */
IntCtrl_Ip_InstallHandler(PIT1_IRQn, PIT_1_ISR, NULL_PTR);
IntCtrl_Ip_EnableIrq(PIT1_IRQn);
C40_Ip_StatusType C40_Ip_Status;
C40_Ip_VirtualSectorsType vSector ;
vSector = C40_Ip_GetSectorNumberFromAddress(FLS_SECTOR_ADDR);
if (STATUS_C40_IP_SECTOR_PROTECTED == C40_Ip_GetLock(vSector))
{
C40_Ip_Status = C40_Ip_ClearLock(vSector, FLS_MASTER_ID);
Fls_ExampleAssert(STATUS_C40_IP_SUCCESS == C40_Ip_Status);
}
Counter = 0;
C40_Ip_Status = Fls_EraseSector(vSector, FLS_MASTER_ID);
Counter = 0;
C40_Ip_Status = Fls_WriteSector(FLS_SECTOR_ADDR,sizeof(TxBuffer),(const uint8 *)TxBuffer,FLS_MASTER_ID);
while(1)
{
test = Pit_Ip_GetCurrentTimer(PIT1_INST, PIT1_CH1);
};
/* If we get here it means the test has passed */
// Exit_Example(TRUE);
// return (0U);
}
#ifdef __cplusplus
}
#endif
/** @} */
Can you share your project so that we can reproduce it and provide corresponding solutions?
The attachment contains my project. PIT1 generates a timer interrupt of 100us, while PIT0 is only used to monitor the time of erasing and writing data flash, without generating an interrupt.
After testing, it was found that writing 80 bytes requires 261us, and during this process, the PIT1 interrupt will not be responded to.
For convenience, I modified some of your code. You can copy it directly into your project and observe the Counter variable through the debugger. I didn't find any problems.
/*
* (c) Copyright 2022 NXP
*
* NXP Confidential. This software is owned or controlled by NXP and may only be used strictly
* in accordance with the applicable license terms. By expressly accepting
* such terms or by downloading, installing, activating and/or otherwise using
* the software, you are agreeing that you have read, and that you agree to
* comply with and are bound by, such license terms. If you do not agree to
* be bound by the applicable license terms, then you may not retain,
* install, activate or otherwise use the software.
*
* This file contains sample code only. It is not part of the production code deliverables.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*==================================================================================================
* INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Clock_Ip.h"
#include "C40_Ip.h"
#include "Pit_Ip.h"
#include "check_example.h"
#include "IntCtrl_Ip.h"
#include "OsIf.h"
#include "String.h"
/*==================================================================================================
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/
/*==================================================================================================
* LOCAL MACROS
==================================================================================================*/
#define FLS_MASTER_ID 0U
#define FLS_BUF_SIZE 1024U
#define FLS_SECTOR_ADDR 0x10000000U
#define FLS_SECTOR_TEST C40_DATA_ARRAY_0_BLOCK_2_S000
#define PIT0_INST 0
#define PIT0_CH0 0
#define PIT1_INST 1
#define PIT1_CH1 1
/*==================================================================================================
* LOCAL CONSTANTS
==================================================================================================*/
/*==================================================================================================
* LOCAL VARIABLES
==================================================================================================*/
/*==================================================================================================
* GLOBAL CONSTANTS
==================================================================================================*/
uint8 TxBuffer[FLS_BUF_SIZE];
uint8 RxBuffer[FLS_BUF_SIZE];
uint32 write_start_time = 0;
uint32 write_end_time = 0;
uint32 write_duration_time = 0;
uint32 erase_start_time = 0;
uint32 erase_end_time = 0;
uint32 erase_duration_time = 0;
uint32 Interrupt_scheduling_cycle = 0;
uint32 current_time = 0;
uint32 last_time = 0;
uint32 test = 0;
uint32 Counter = 0;
/*==================================================================================================
* GLOBAL VARIABLES
==================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTION PROTOTYPES
==================================================================================================*/
void Fls_InitBuffers(void);
void Fls_ExampleAssert(boolean Condition);
/* External functions and variables */
extern ISR(PIT_1_ISR);
/*==================================================================================================
* LOCAL FUNCTIONS
==================================================================================================*/
/**
* @brief Implement a simple assert macro
*
* @Param Condition
* @return void
*/
void Fls_ExampleAssert(boolean Condition)
{
while (!Condition)
{
/* Loop forever */
}
}
void Fls_InitBuffers(void)
{
uint32 Index;
for (Index = 0U; Index < FLS_BUF_SIZE; Index++)
{
TxBuffer[Index] = (uint8)0xaa;
RxBuffer[Index] = 0U;
}
}
C40_Ip_StatusType __attribute__((section (".ramcode"))) Fls_WriteSector(volatile uint32 u32LogicalAddress, uint32 u32Length,const uint8 *pSourceAddressPtr, uint8 u8DomainIdValue)
{
C40_Ip_StatusType C40_Ip_Status = STATUS_C40_IP_ERROR ;
uint32_t writeLen = 0u ;
while (u32Length > 0)
{
if(u32Length > 128)
{
writeLen = 128 ;
}
else
{
writeLen = u32Length ;
}
/* Write data */
C40_Ip_Status = C40_Ip_MainInterfaceWrite(u32LogicalAddress,writeLen,(const uint8_t*) pSourceAddressPtr, u8DomainIdValue);
do
{
C40_Ip_Status = C40_Ip_MainInterfaceWriteStatus();
} while (STATUS_C40_IP_BUSY == C40_Ip_Status);
u32LogicalAddress += writeLen;
pSourceAddressPtr += writeLen;
u32Length -= writeLen;
}
return C40_Ip_Status ;
}
C40_Ip_StatusType __attribute__((section (".ramcode"))) Fls_EraseSector(C40_Ip_VirtualSectorsType Fls_VirtualSector,uint8 u8DomainIdValue)
{
C40_Ip_StatusType C40_Ip_Status = STATUS_C40_IP_ERROR ;
/* Erase sector */
C40_Ip_MainInterfaceSectorErase(Fls_VirtualSector, u8DomainIdValue);
do
{
C40_Ip_Status = C40_Ip_MainInterfaceSectorEraseStatus();
}
while (STATUS_C40_IP_BUSY == C40_Ip_Status);
return C40_Ip_Status ;
}
/* Callback functions definition */
void Pit1_Ch1_Callback (uint8 channel)
{
(void)channel;
Counter++;
}
/*==================================================================================================
* GLOBAL FUNCTIONS
==================================================================================================*/
/**
* @brief Main function of the example
* @details Initializes IP C40 driver and erase, write, read internal flash memory
*/
void main(void)
{
uint32 Index;
C40_Ip_StatusType C40Status;
Clock_Ip_StatusType ClockStatus;
/* Initialize clock */
ClockStatus = Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);
Fls_ExampleAssert(ClockStatus == CLOCK_IP_SUCCESS);
/* OsIf initialization */
OsIf_Init(NULL);
/* Initialize C40 driver */
C40Status = C40_Ip_Init(&C40ConfigSet_VS_0_InitCfg);
Fls_ExampleAssert(STATUS_C40_IP_SUCCESS == C40Status);
/* Initialize buffers */
Fls_InitBuffers();
/* PIT timer and interrupt configuration */
Pit_Ip_Init(PIT0_INST, &PIT_0_InitConfig_PB);
Pit_Ip_Init(PIT1_INST, &PIT_1_InitConfig_PB);
Pit_Ip_InitChannel(PIT0_INST, &PIT_0_ChannelConfig_PB[0]);
Pit_Ip_InitChannel(PIT1_INST, &PIT_1_ChannelConfig_PB[0]);
/* PIT0_CH0 period is 100mS since its clock is AIPS_SLOW_CLK 40MHz */
Pit_Ip_StartChannel(PIT0_INST, PIT0_CH0, 4000000);
Pit_Ip_StartChannel(PIT1_INST, PIT1_CH1, 400); //10us interrupt
Pit_Ip_EnableChannelInterrupt(PIT1_INST, PIT1_CH1);
/* Install IRQ handler for PIT0 */
IntCtrl_Ip_InstallHandler(PIT1_IRQn, PIT_1_ISR, NULL_PTR);
IntCtrl_Ip_EnableIrq(PIT1_IRQn);
C40_Ip_StatusType C40_Ip_Status;
C40_Ip_VirtualSectorsType vSector ;
vSector = C40_Ip_GetSectorNumberFromAddress(FLS_SECTOR_ADDR);
if (STATUS_C40_IP_SECTOR_PROTECTED == C40_Ip_GetLock(vSector))
{
C40_Ip_Status = C40_Ip_ClearLock(vSector, FLS_MASTER_ID);
Fls_ExampleAssert(STATUS_C40_IP_SUCCESS == C40_Ip_Status);
}
Counter = 0;
C40_Ip_Status = Fls_EraseSector(vSector, FLS_MASTER_ID);
Counter = 0;
C40_Ip_Status = Fls_WriteSector(FLS_SECTOR_ADDR,sizeof(TxBuffer),(const uint8 *)TxBuffer,FLS_MASTER_ID);
while(1)
{
test = Pit_Ip_GetCurrentTimer(PIT1_INST, PIT1_CH1);
};
/* If we get here it means the test has passed */
// Exit_Example(TRUE);
// return (0U);
}
#ifdef __cplusplus
}
#endif
/** @} */
Thank you very much. I tested your modified project and it succeed.
The method of executing the erase and programming operation functions for data flash in RAM solved my problem.
Thanks for the info, I'll check it out, it will take time to process it.