2 Replies Latest reply on Nov 16, 2020 8:03 AM by DoBa_1705086

    Changing the Interrupt Mask Level in PSOC5


      This post describes how to add the ability to change the interrupt priority mask level within the PSOC5 family using the functionality of the basepri register and normally provided by the CMSIS function __set_BASEPRI(priority) even though the PSOC software library does not define this function.


      I suggest that Cypress/Infineon software team members update the PSOC Creator system and libraries to make these functions available on the ARM M3 core products.  I am sharing my work-around for others in the meantime.



      In a project that I have been developing using the CY8C5888LTI (PSOC-5), I had the need to selectively raise the interrupt mask level to protect linked list structures which are manipulated both within interrupt service routines and non-interrupt code.  I could not use the typical CyEnterCriticalSection() / CyExitCriticalSection() functions which mask ALL interrupts due to the fact that I am using the SPI interface with software buffers.  The SPI API for the software buffers utilizes DMA and it is necessary to permit these interrupts to continue to function while blocking lower urgency (higher interrupt priority number) interrupts.


      Unfortunately, the PSOC API's do not include the standard CMSIS functions __get_BASEPRI() and  __set_BASEPRI(priority).  While these function can be found within the PSOC generated source file cmsis_gcc.h, they are wrapped within a #ifdef that only makes the functions visible for 7M and 8M ARM architecture chips.  Yet the ARM M3 core upon which PSOC5 is based does include the basepri register and these functions do work.



      An excellent treatise on ARM interrupt priorities can be found here:  Cutting Through the Confusion with ARM Cortex-M Interrupt Priorities « State Space



      Rather than simply copying the unavailable inline function definitions for __get_BASEPRI() / __set_BASEPRI() from within cmsis_gcc.h and placing them within a new header.h file, I chose to implement more human readable functions getInterruptMask() and setInterruptMask(level).  These functions return and set (respectively) the integer interrupt level, whereas the CMSIS functions return and pass a value that is the actual interrupt level shifted into the most significant 3 (or 4) bits of the basepri register. 


      The attached file intmask.h defines these always inline functions for use in projects that need this capability.  Note that it is left to the user to appropriately manage the interrupt priority levels used by the various hardware elements of their project!


      Regards, Doug Bartlett