mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 01:05:54 +08:00
ESP32: Need to take priority into account when allocating CPU interrupts
This commit is contained in:
@@ -297,11 +297,17 @@
|
||||
* 26 can be mapped to peripheral interrupts:
|
||||
*
|
||||
* Level triggered peripherals (21 total):
|
||||
* 0-5, 8-9, 12-13, 17-21, 23-27, 31
|
||||
* 0-5, 8-9, 12-13, 17-18 - Priority 1
|
||||
* 19-21 - Priority 2
|
||||
* 23, 27 - Priority 3
|
||||
* 24-25 - Priority 4
|
||||
* 26, 31 - Priority 5
|
||||
* Edge triggered peripherals (4 total):
|
||||
* 10, 22, 28, 30
|
||||
* 10 - Priority 1
|
||||
* 22 - Priority 3
|
||||
* 28, 30 - Priority 4
|
||||
* NMI (1 total):
|
||||
* 14
|
||||
* 14 - NMI
|
||||
*
|
||||
* CPU peripheral interrupts can be a assigned to a CPU interrupt using the
|
||||
* PRO_*_MAP_REG or APP_*_MAP_REG. There are a pair of these registers for
|
||||
@@ -310,11 +316,12 @@
|
||||
*
|
||||
* The remaining, five, internal CPU interrupts are:
|
||||
*
|
||||
* 6 Timer0
|
||||
* 7 Software
|
||||
* 15 Timer1
|
||||
* 16 Timer2
|
||||
* 29 Software
|
||||
* 6 Timer0 - Priority 1
|
||||
* 7 Software - Priority 1
|
||||
* 11 Profiling - Priority 3
|
||||
* 15 Timer1 - Priority 3
|
||||
* 16 Timer2 - Priority 5
|
||||
* 29 Software - Priority 3
|
||||
*
|
||||
* A peripheral interrupt can be disabled
|
||||
*/
|
||||
@@ -359,6 +366,21 @@
|
||||
#define EPS32_CPUINT_PERIPHSET 0xdffe7f3f
|
||||
#define EPS32_CPUINT_INTERNALSET 0x200180c0
|
||||
|
||||
/* Priority 1: 0-10, 12-13, 17-18 (15)
|
||||
* Priority 2: 19-21 (3)
|
||||
* Priority 3: 11, 15, 22-23, 27, 29 (6)
|
||||
* Priority 4: 24-25, 28, 30 (4)
|
||||
* Priority 5: 16, 26, 31 (3)
|
||||
* Priority NMI: 14 (1)
|
||||
*/
|
||||
|
||||
#define ESP32_INTPRI1_MASK 0x000637ff
|
||||
#define ESP32_INTPRI2_MASK 0x00380000
|
||||
#define ESP32_INTPRI3_MASK 0x28c08800
|
||||
#define ESP32_INTPRI4_MASK 0x53000000
|
||||
#define ESP32_INTPRI5_MASK 0x84010000
|
||||
#define ESP32_INTNMI_MASK 0x00004000
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
@@ -143,6 +143,12 @@
|
||||
|
||||
#define NO_CPUINT ESP32_CPUINT_TIMER0
|
||||
|
||||
/* Priority range is 1-5 */
|
||||
|
||||
#define ESP32_MIN_PRIORITY 1
|
||||
#define ESP32_MAX_PRIORITY 5
|
||||
#define ESP32_PRIO_INDEX(p) ((p) - ESP32_MIN_PRIORITY)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@@ -166,6 +172,17 @@ static uint32_t g_intenable[1];
|
||||
static uint32_t g_level_ints = ESP32_LEVEL_SET;
|
||||
static uint32_t g_edge_ints = ESP32_EDGE_SET;
|
||||
|
||||
/* Bitsets for each interrupt priority 1-5 */
|
||||
|
||||
static uint32_t g_priority[5] =
|
||||
{
|
||||
ESP32_INTPRI1_MASK,
|
||||
ESP32_INTPRI2_MASK,
|
||||
ESP32_INTPRI3_MASK,
|
||||
ESP32_INTPRI4_MASK,
|
||||
ESP32_INTPRI5_MASK
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -229,7 +246,7 @@ void up_enable_irq(int cpuint)
|
||||
* Allocate a level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
* priority - Priority of the CPU interrupt (1-5)
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated level-sensitive, CPU interrupt numbr is
|
||||
@@ -239,28 +256,39 @@ void up_enable_irq(int cpuint)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_levelint(void)
|
||||
int esp32_alloc_levelint(int priority)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
uint32_t intset;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY && priority <= ESP32_MAX_PRIORITY)
|
||||
|
||||
/* Check if there are any level CPU interrupts available */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if ((g_level_ints & ESP32_LEVEL_SET) != 0)
|
||||
{
|
||||
/* Search for an unallocated CPU interrupt number in g_level_ints. */
|
||||
|
||||
for (cpuint = 0; cpuint < ESP32_CPUINT_NLEVELPERIPHS; cpuint++)
|
||||
intset = g_level_ints & g_priority[ESP32_PRIO_INDEX(priority)] & ESP32_LEVEL_SET;
|
||||
if (intset != 0)
|
||||
{
|
||||
/* Skip over initial zeroes as quickly in groups of 8 bits. */
|
||||
|
||||
for (cpuint = 0, mask = 0xff;
|
||||
cpuint <= ESP32_CPUINT_MAX && (intset & mask) == 0;
|
||||
cpuint += 8, mask <<= 8);
|
||||
|
||||
/* Search for an unallocated CPU interrupt number in the remaining intset. */
|
||||
|
||||
for (; cpuint <= ESP32_CPUINT_MAX && intset != 0; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((g_level_ints & mask) != 0)
|
||||
if ((intset & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
@@ -268,6 +296,10 @@ int esp32_alloc_levelint(void)
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear the bit in intset so that we may exit the loop sooner */
|
||||
|
||||
intset &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +344,7 @@ void esp32_free_levelint(int cpuint)
|
||||
* Allocate an edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
* priority - Priority of the CPU interrupt (1-5)
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated edge-sensitive, CPU interrupt numbr is
|
||||
@@ -322,28 +354,39 @@ void esp32_free_levelint(int cpuint)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_edgeint(void)
|
||||
int esp32_alloc_edgeint(int priority)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
uint32_t intset;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY && priority <= ESP32_MAX_PRIORITY)
|
||||
|
||||
/* Check if there are any level CPU interrupts available */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if ((g_edge_ints & ESP32_EDGE_SET) != 0)
|
||||
{
|
||||
/* Search for an unallocated CPU interrupt number in g_edge_ints. */
|
||||
|
||||
for (cpuint = 0; cpuint < ESP32_CPUINT_NEDGEPERIPHS; cpuint++)
|
||||
intset = g_edge_ints & g_priority[ESP32_PRIO_INDEX(priority)] & ESP32_EDGE_SET;
|
||||
if (intset != 0)
|
||||
{
|
||||
/* Skip over initial zeroes as quickly in groups of 8 bits. */
|
||||
|
||||
for (cpuint = 0, mask = 0xff;
|
||||
cpuint <= ESP32_CPUINT_MAX && (intset & mask) == 0;
|
||||
cpuint += 8, mask <<= 8);
|
||||
|
||||
/* Search for an unallocated CPU interrupt number in the remaining intset. */
|
||||
|
||||
for (; cpuint <= ESP32_CPUINT_MAX && intset != 0; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((g_edge_ints & mask) != 0)
|
||||
if ((intset & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
@@ -351,6 +394,10 @@ int esp32_alloc_edgeint(void)
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear the bit in intset so that we may exit the loop sooner */
|
||||
|
||||
intset &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
* Allocate a level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
* priority - Priority of the CPU interrupt (1-5)
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated level-sensitive, CPU interrupt numbr is
|
||||
@@ -63,7 +63,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_levelint(void);
|
||||
int esp32_alloc_levelint(int priority);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_levelint
|
||||
@@ -72,7 +72,7 @@ int esp32_alloc_levelint(void);
|
||||
* Free a previoulsy allocated level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
* cpuint - The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@@ -88,7 +88,7 @@ void esp32_free_levelint(int cpuint);
|
||||
* Allocate an edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
* priority - Priority of the CPU interrupt (1-5)
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated edge-sensitive, CPU interrupt numbr is
|
||||
@@ -98,7 +98,7 @@ void esp32_free_levelint(int cpuint);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_edgeint(void);
|
||||
int esp32_alloc_edgeint(int priority);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_edgeint
|
||||
@@ -107,14 +107,14 @@ int esp32_alloc_edgeint(void);
|
||||
* Free a previoulsy allocated edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
* cpuint - The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_edgeint(int cpuint);
|
||||
void esp32_free_edgeint(int cpuint, int priority);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_attach_peripheral
|
||||
|
||||
Reference in New Issue
Block a user