Add an argument to ISRs. Disable interrupts while masking them.
This commit is contained in:
parent
ec5dabd237
commit
5583543f14
16 changed files with 87 additions and 59 deletions
|
@ -153,7 +153,7 @@ void IRAM PendSV(enum SVC_ReqType req)
|
|||
*/
|
||||
extern portBASE_TYPE sdk_MacIsrSigPostDefHdl(void);
|
||||
|
||||
void IRAM SV_ISR(void)
|
||||
void IRAM SV_ISR(void *arg)
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE ;
|
||||
if(pending_maclayer_sv)
|
||||
|
@ -185,11 +185,11 @@ void xPortSysTickHandle (void)
|
|||
*/
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
_xt_isr_attach(INUM_SOFT, SV_ISR);
|
||||
_xt_isr_attach(INUM_SOFT, SV_ISR, NULL);
|
||||
_xt_isr_unmask(BIT(INUM_SOFT));
|
||||
|
||||
/* Initialize system tick timer interrupt and schedule the first tick. */
|
||||
_xt_isr_attach(INUM_TICK, sdk__xt_timer_int);
|
||||
_xt_isr_attach(INUM_TICK, sdk__xt_timer_int, NULL);
|
||||
_xt_isr_unmask(BIT(INUM_TICK));
|
||||
sdk__xt_tick_timer_init();
|
||||
|
||||
|
|
|
@ -58,17 +58,17 @@ void gpio_set_pullup(uint8_t gpio_num, bool enabled, bool enabled_during_sleep)
|
|||
|
||||
static gpio_interrupt_handler_t gpio_interrupt_handlers[16] = { 0 };
|
||||
|
||||
void __attribute__((weak)) IRAM gpio_interrupt_handler(void)
|
||||
void __attribute__((weak)) IRAM gpio_interrupt_handler(void *arg)
|
||||
{
|
||||
uint32_t status_reg = GPIO.STATUS;
|
||||
GPIO.STATUS_CLEAR = status_reg;
|
||||
|
||||
uint8_t gpio_idx;
|
||||
while((gpio_idx = __builtin_ffs(status_reg)))
|
||||
while ((gpio_idx = __builtin_ffs(status_reg)))
|
||||
{
|
||||
gpio_idx--;
|
||||
status_reg &= ~BIT(gpio_idx);
|
||||
if(FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_idx])) {
|
||||
if (FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_idx])) {
|
||||
gpio_interrupt_handler_t handler = gpio_interrupt_handlers[gpio_idx];
|
||||
if (handler) {
|
||||
handler(gpio_idx);
|
||||
|
@ -82,8 +82,8 @@ void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type, g
|
|||
gpio_interrupt_handlers[gpio_num] = handler;
|
||||
|
||||
GPIO.CONF[gpio_num] = SET_FIELD(GPIO.CONF[gpio_num], GPIO_CONF_INTTYPE, int_type);
|
||||
if(int_type != GPIO_INTTYPE_NONE) {
|
||||
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler);
|
||||
if (int_type != GPIO_INTTYPE_NONE) {
|
||||
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler, NULL);
|
||||
_xt_isr_unmask(1<<INUM_GPIO);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,19 @@
|
|||
*/
|
||||
#include <esp/interrupts.h>
|
||||
|
||||
_xt_isr isr[16];
|
||||
typedef struct _xt_isr_entry_ {
|
||||
_xt_isr handler;
|
||||
void *arg;
|
||||
} _xt_isr_entry;
|
||||
|
||||
_xt_isr_entry isr[16];
|
||||
|
||||
bool esp_in_isr;
|
||||
|
||||
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func)
|
||||
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func, void *arg)
|
||||
{
|
||||
isr[i] = func;
|
||||
isr[i].handler = func;
|
||||
isr[i].arg = arg;
|
||||
}
|
||||
|
||||
/* Generic ISR handler.
|
||||
|
@ -25,17 +31,20 @@ uint16_t IRAM _xt_isr_handler(uint16_t intset)
|
|||
esp_in_isr = true;
|
||||
|
||||
/* WDT has highest priority (occasional WDT resets otherwise) */
|
||||
if(intset & BIT(INUM_WDT)) {
|
||||
if (intset & BIT(INUM_WDT)) {
|
||||
_xt_clear_ints(BIT(INUM_WDT));
|
||||
isr[INUM_WDT]();
|
||||
isr[INUM_WDT].handler(NULL);
|
||||
intset -= BIT(INUM_WDT);
|
||||
}
|
||||
|
||||
while(intset) {
|
||||
while (intset) {
|
||||
uint8_t index = __builtin_ffs(intset) - 1;
|
||||
uint16_t mask = BIT(index);
|
||||
_xt_clear_ints(mask);
|
||||
isr[index]();
|
||||
_xt_isr handler = isr[index].handler;
|
||||
if (handler) {
|
||||
handler(isr[index].arg);
|
||||
}
|
||||
intset -= mask;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ typedef void (* gpio_interrupt_handler_t)(uint8_t gpio_num);
|
|||
*
|
||||
* Example:
|
||||
*
|
||||
* void IRAM gpio_interrupt_handler(void) {
|
||||
* void IRAM gpio_interrupt_handler(void *arg) {
|
||||
* // check GPIO.STATUS
|
||||
* // write GPIO.STATUS_CLEAR
|
||||
* // Do something when GPIO changes
|
||||
|
|
|
@ -35,19 +35,37 @@ typedef enum {
|
|||
INUM_TIMER_FRC2 = 10,
|
||||
} xt_isr_num_t;
|
||||
|
||||
void sdk__xt_int_exit (void);
|
||||
void _xt_user_exit (void);
|
||||
void sdk__xt_tick_timer_init (void);
|
||||
void sdk__xt_timer_int(void);
|
||||
void sdk__xt_int_exit(void);
|
||||
void _xt_user_exit(void);
|
||||
void sdk__xt_tick_timer_init(void);
|
||||
void sdk__xt_timer_int(void *);
|
||||
void sdk__xt_timer_int1(void);
|
||||
|
||||
/* The normal running level is 0.
|
||||
* The system tick isr, timer frc2_isr, sv_isr etc run at level 1.
|
||||
* Debug exceptions run at level 2?
|
||||
* The wdev nmi runs at level 3.
|
||||
*/
|
||||
static inline uint32_t _xt_get_intlevel(void)
|
||||
{
|
||||
uint32_t level;
|
||||
__asm__ volatile("rsr %0, intlevel" : "=a"(level));
|
||||
return level;
|
||||
__asm__ volatile("rsr %0, ps" : "=a"(level));
|
||||
return level & 0xf;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are conflicting definitions for XCHAL_EXCM_LEVEL. Newlib
|
||||
* defines it to be 1 and xtensa_rtos.h defines it to be 3. Don't want
|
||||
* 3 as that is for the NMI and might want to check that the OS apis
|
||||
* are not entered in level 3. Setting the interrupt level to 3 does
|
||||
* not disable the NMI anyway. So set the level to 2.
|
||||
*/
|
||||
|
||||
#ifdef XCHAL_EXCM_LEVEL
|
||||
#undef XCHAL_EXCM_LEVEL
|
||||
#define XCHAL_EXCM_LEVEL 2
|
||||
#endif
|
||||
|
||||
/* Disable interrupts and return the old ps value, to pass into
|
||||
_xt_restore_interrupts later.
|
||||
|
||||
|
@ -68,25 +86,27 @@ static inline void _xt_restore_interrupts(uint32_t new_ps)
|
|||
__asm__ volatile ("wsr %0, ps; rsync" :: "a" (new_ps));
|
||||
}
|
||||
|
||||
/* ESPTODO: the mask/unmask functions aren't thread safe */
|
||||
|
||||
static inline void _xt_isr_unmask(uint32_t unmask)
|
||||
static inline uint32_t _xt_isr_unmask(uint32_t unmask)
|
||||
{
|
||||
uint32_t old_level = _xt_disable_interrupts();
|
||||
uint32_t intenable;
|
||||
asm volatile ("rsr %0, intenable" : "=a" (intenable));
|
||||
intenable |= unmask;
|
||||
asm volatile ("wsr %0, intenable; esync" :: "a" (intenable));
|
||||
asm volatile ("wsr %0, intenable;" :: "a" (intenable | unmask));
|
||||
_xt_restore_interrupts(old_level);
|
||||
return intenable;
|
||||
}
|
||||
|
||||
static inline void _xt_isr_mask (uint32_t mask)
|
||||
static inline uint32_t _xt_isr_mask(uint32_t mask)
|
||||
{
|
||||
uint32_t old_level = _xt_disable_interrupts();
|
||||
uint32_t intenable;
|
||||
asm volatile ("rsr %0, intenable" : "=a" (intenable));
|
||||
intenable &= ~mask;
|
||||
asm volatile ("wsr %0, intenable; esync" :: "a" (intenable));
|
||||
asm volatile ("wsr %0, intenable;" :: "a" (intenable & ~mask));
|
||||
_xt_restore_interrupts(old_level);
|
||||
return intenable;
|
||||
}
|
||||
|
||||
static inline uint32_t _xt_read_ints (void)
|
||||
static inline uint32_t _xt_read_ints(void)
|
||||
{
|
||||
uint32_t interrupt;
|
||||
asm volatile ("rsr %0, interrupt" : "=a" (interrupt));
|
||||
|
@ -98,9 +118,7 @@ static inline void _xt_clear_ints(uint32_t mask)
|
|||
asm volatile ("wsr %0, intclear; esync" :: "a" (mask));
|
||||
}
|
||||
|
||||
typedef void (* _xt_isr)(void);
|
||||
/* This function is implemeneted in FreeRTOS port.c at the moment,
|
||||
should be moved or converted to an inline */
|
||||
void _xt_isr_attach (uint8_t i, _xt_isr func);
|
||||
typedef void (* _xt_isr)(void *arg);
|
||||
void _xt_isr_attach (uint8_t i, _xt_isr func, void *arg);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,13 +17,13 @@ const int freq_frc2 = 10;
|
|||
static volatile uint32_t frc1_count;
|
||||
static volatile uint32_t frc2_count;
|
||||
|
||||
void frc1_interrupt_handler(void)
|
||||
void frc1_interrupt_handler(void *arg)
|
||||
{
|
||||
frc1_count++;
|
||||
gpio_toggle(gpio_frc1);
|
||||
}
|
||||
|
||||
void frc2_interrupt_handler(void)
|
||||
void frc2_interrupt_handler(void *arg)
|
||||
{
|
||||
/* FRC2 needs the match register updated on each timer interrupt */
|
||||
timer_set_frequency(FRC2, freq_frc2);
|
||||
|
@ -47,8 +47,8 @@ void user_init(void)
|
|||
timer_set_run(FRC2, false);
|
||||
|
||||
/* set up ISRs */
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler, NULL);
|
||||
_xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler, NULL);
|
||||
|
||||
/* configure timer frequencies */
|
||||
timer_set_frequency(FRC1, freq_frc1);
|
||||
|
|
|
@ -97,7 +97,7 @@ void timerRegTask(void *pvParameters)
|
|||
}
|
||||
}
|
||||
|
||||
IRAM void frc1_handler(void)
|
||||
IRAM void frc1_handler(void *arg)
|
||||
{
|
||||
frc1_handler_call_count++;
|
||||
frc1_last_count_val = TIMER(0).COUNT;
|
||||
|
@ -106,7 +106,7 @@ IRAM void frc1_handler(void)
|
|||
//TIMER_FRC1_MATCH_REG = frc1_last_count_val + 0x100000;
|
||||
}
|
||||
|
||||
void frc2_handler(void)
|
||||
void frc2_handler(void *arg)
|
||||
{
|
||||
frc2_handler_call_count++;
|
||||
frc2_last_count_val = TIMER(1).COUNT;
|
||||
|
@ -127,9 +127,9 @@ void user_init(void)
|
|||
TIMER(1).LOAD = VAL2FIELD(TIMER_CTRL_CLKDIV, TIMER_CLKDIV_256);
|
||||
|
||||
DPORT.INT_ENABLE |= DPORT_INT_ENABLE_TIMER0 | DPORT_INT_ENABLE_TIMER1;
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_handler, NULL);
|
||||
_xt_isr_unmask(1<<INUM_TIMER_FRC1);
|
||||
_xt_isr_attach(INUM_TIMER_FRC2, frc2_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC2, frc2_handler, NULL);
|
||||
_xt_isr_unmask(1<<INUM_TIMER_FRC2);
|
||||
|
||||
TIMER(0).CTRL |= TIMER_CTRL_RUN;
|
||||
|
|
|
@ -237,7 +237,7 @@ static volatile bool frc1_ran;
|
|||
static volatile bool frc1_finished;
|
||||
static volatile char frc1_buf[80];
|
||||
|
||||
static void frc1_interrupt_handler(void)
|
||||
static void frc1_interrupt_handler(void *arg)
|
||||
{
|
||||
frc1_ran = true;
|
||||
timer_set_run(FRC1, false);
|
||||
|
@ -250,7 +250,7 @@ static void test_isr()
|
|||
printf("Testing behaviour inside ISRs...\r\n");
|
||||
timer_set_interrupts(FRC1, false);
|
||||
timer_set_run(FRC1, false);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler, NULL);
|
||||
timer_set_frequency(FRC1, 1000);
|
||||
timer_set_interrupts(FRC1, true);
|
||||
timer_set_run(FRC1, true);
|
||||
|
|
|
@ -88,7 +88,7 @@ static inline void init_descriptors_list()
|
|||
}
|
||||
|
||||
// DMA interrupt handler. It is called each time a DMA block is finished processing.
|
||||
static void dma_isr_handler(void)
|
||||
static void dma_isr_handler(void *args)
|
||||
{
|
||||
portBASE_TYPE task_awoken = pdFALSE;
|
||||
|
||||
|
@ -168,7 +168,7 @@ void play_task(void *pvParameters)
|
|||
|
||||
i2s_pins_t i2s_pins = {.data = true, .clock = true, .ws = true};
|
||||
|
||||
i2s_dma_init(dma_isr_handler, clock_div, i2s_pins);
|
||||
i2s_dma_init(dma_isr_handler, NULL, clock_div, i2s_pins);
|
||||
|
||||
while (1) {
|
||||
init_descriptors_list();
|
||||
|
|
|
@ -62,7 +62,7 @@ void sdk_rom_i2c_writeReg_Mask(uint32_t block, uint32_t host_id,
|
|||
reg_add##_lsb, indata)
|
||||
|
||||
|
||||
void i2s_dma_init(i2s_dma_isr_t isr, i2s_clock_div_t clock_div, i2s_pins_t pins)
|
||||
void i2s_dma_init(i2s_dma_isr_t isr, void *arg, i2s_clock_div_t clock_div, i2s_pins_t pins)
|
||||
{
|
||||
// reset DMA
|
||||
SET_MASK_BITS(SLC.CONF0, SLC_CONF0_RX_LINK_RESET);
|
||||
|
@ -83,7 +83,7 @@ void i2s_dma_init(i2s_dma_isr_t isr, i2s_clock_div_t clock_div, i2s_pins_t pins)
|
|||
SLC_RX_DESCRIPTOR_CONF_RX_EOF_MODE | SLC_RX_DESCRIPTOR_CONF_RX_FILL_MODE);
|
||||
|
||||
if (isr) {
|
||||
_xt_isr_attach(INUM_SLC, isr);
|
||||
_xt_isr_attach(INUM_SLC, isr, arg);
|
||||
SET_MASK_BITS(SLC.INT_ENABLE, SLC_INT_ENABLE_RX_EOF);
|
||||
SLC.INT_CLEAR = 0xFFFFFFFF;
|
||||
_xt_isr_unmask(1<<INUM_SLC);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*i2s_dma_isr_t)(void);
|
||||
typedef void (*i2s_dma_isr_t)(void *);
|
||||
|
||||
typedef struct dma_descriptor {
|
||||
uint32_t blocksize:12;
|
||||
|
@ -61,10 +61,11 @@ typedef struct {
|
|||
* Initialize I2S and DMA subsystems.
|
||||
*
|
||||
* @param isr ISR handler. Can be NULL if interrupt handling is not needed.
|
||||
* @param arg ISR handler arg.
|
||||
* @param clock_div I2S clock configuration.
|
||||
* @param pins I2S pin configuration. Specifies which pins are enabled in I2S.
|
||||
*/
|
||||
void i2s_dma_init(i2s_dma_isr_t isr, i2s_clock_div_t clock_div, i2s_pins_t pins);
|
||||
void i2s_dma_init(i2s_dma_isr_t isr, void *arg, i2s_clock_div_t clock_div, i2s_pins_t pins);
|
||||
|
||||
/**
|
||||
* Calculate I2S dividers for the specified frequency.
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct pwmInfoDefinition
|
|||
|
||||
static PWMInfo pwmInfo;
|
||||
|
||||
static void frc1_interrupt_handler(void)
|
||||
static void frc1_interrupt_handler(void *arg)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
bool out = true;
|
||||
|
@ -97,7 +97,7 @@ void pwm_init(uint8_t npins, const uint8_t* pins)
|
|||
pwm_stop();
|
||||
|
||||
/* set up ISRs */
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler, NULL);
|
||||
|
||||
/* Flag not running */
|
||||
pwmInfo.running = 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ static SemaphoreHandle_t uart0_sem = NULL;
|
|||
static bool inited = false;
|
||||
static void uart0_rx_init(void);
|
||||
|
||||
IRAM void uart0_rx_handler(void)
|
||||
IRAM void uart0_rx_handler(void *arg)
|
||||
{
|
||||
// TODO: Handle UART1, see reg 0x3ff20020, bit2, bit0 represents uart1 and uart0 respectively
|
||||
if (!UART(UART0).INT_STATUS & UART_INT_STATUS_RXFIFO_FULL) {
|
||||
|
@ -97,7 +97,7 @@ static void uart0_rx_init(void)
|
|||
int trig_lvl = 1;
|
||||
uart0_sem = xSemaphoreCreateCounting(UART0_RX_SIZE, 0);
|
||||
|
||||
_xt_isr_attach(INUM_UART, uart0_rx_handler);
|
||||
_xt_isr_attach(INUM_UART, uart0_rx_handler, NULL);
|
||||
_xt_isr_unmask(1 << INUM_UART);
|
||||
|
||||
// reset the rx fifo
|
||||
|
|
|
@ -60,7 +60,7 @@ volatile uint32_t dma_isr_counter = 0;
|
|||
|
||||
static volatile bool i2s_dma_processing = false;
|
||||
|
||||
static void dma_isr_handler(void)
|
||||
static void dma_isr_handler(void *arg)
|
||||
{
|
||||
if (i2s_dma_is_eof_interrupt()) {
|
||||
#ifdef WS2812_I2S_DEBUG
|
||||
|
@ -145,7 +145,7 @@ void ws2812_i2s_init(uint32_t pixels_number)
|
|||
debug("i2s clock dividers, bclk=%d, clkm=%d\n",
|
||||
clock_div.bclk_div, clock_div.clkm_div);
|
||||
|
||||
i2s_dma_init(dma_isr_handler, clock_div, i2s_pins);
|
||||
i2s_dma_init(dma_isr_handler, NULL, clock_div, i2s_pins);
|
||||
}
|
||||
|
||||
const IRAM_DATA int16_t bitpatterns[16] =
|
||||
|
|
|
@ -69,7 +69,7 @@ void IRAM sdk__xt_int_exit(void) {
|
|||
");
|
||||
}
|
||||
|
||||
void IRAM sdk__xt_timer_int(void) {
|
||||
void IRAM sdk__xt_timer_int(void *arg) {
|
||||
uint32_t trigger_ccount;
|
||||
uint32_t current_ccount;
|
||||
uint32_t ccount_interval = portTICK_PERIOD_MS * sdk_os_get_cpu_frequency() * 1000;
|
||||
|
|
|
@ -290,7 +290,7 @@ static void a_03_byte_load_test_isr()
|
|||
printf("Testing behaviour inside ISRs...\r\n");
|
||||
timer_set_interrupts(FRC1, false);
|
||||
timer_set_run(FRC1, false);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler);
|
||||
_xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler, NULL);
|
||||
timer_set_frequency(FRC1, 1000);
|
||||
timer_set_interrupts(FRC1, true);
|
||||
timer_set_run(FRC1, true);
|
||||
|
|
Loading…
Reference in a new issue