ESP8266 Developer Zone The Official ESP8266 Forum 2015-01-16T19:16:15+08:00 https://bbs.espressif.com:443/feed.php?f=7&t=119 2015-01-16T19:16:15+08:00 2015-01-16T19:16:15+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=511#p511 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]>
FrenkR wrote:
12 is just a "some" number that is passed to INT routine and has nothing to do with GPIO or INT functionality. Check documentation.


Thanks Frenk,

The documentation I have so far shows this:

Code:

ETS_GPIO_INTR_ATTACH (func, arg)
Sign GPIO interrupt handler


So, I'm guessing whatever gets passed in as "arg", ends up being "key" in the interrupt handler:

Code:

// GPIO interrupt handler:store local data and start task
static void ICACHE_FLASH_ATTR
iw_GPIO_handler(int8_t key){


which in your case is not used.

Bruce

Statistics: Posted by brucehvn — Fri Jan 16, 2015 7:16 pm


]]>
2015-01-15T07:42:30+08:00 2015-01-15T07:42:30+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=504#p504 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]> Statistics: Posted by FrenkR — Thu Jan 15, 2015 7:42 am


]]>
2015-01-14T11:00:20+08:00 2015-01-14T11:00:20+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=499#p499 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]>

Code:

   // GPIO12 interrupt handler
   ETS_GPIO_INTR_ATTACH(iw_GPIO_handler, 12);

   ...

    // interrupt on GPIO 13
   gpio_pin_intr_state_set(GPIO_ID_PIN(13), GPIO_PIN_INTR_POSEDGE); // | GPIO_PIN_INTR_NEGEDGE); // Interrupt on any GPIO13 edge
   gpio_pin_intr_state_set(GPIO_ID_PIN(14), GPIO_PIN_INTR_DISABLE);
 


Bruce

Statistics: Posted by brucehvn — Wed Jan 14, 2015 11:00 am


]]>
2015-01-13T06:39:00+08:00 2015-01-13T06:39:00+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=486#p486 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]> Statistics: Posted by FrenkR — Tue Jan 13, 2015 6:39 am


]]>
2015-01-12T12:25:41+08:00 2015-01-12T12:25:41+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=479#p479 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]>
FrenkR wrote:
have following situation. On GPIO13, button is defined(input, pullup). interrupt trigger is set to GPIO13. trigger posts "message" to a task. inside task routine, GPIO14 is set to 0/1 (relay). After pressing a button on GPIO13 few times, module resets itself:

Code:

rst cause:4, boot mode:(1,7)
wdt reset

Also interrupt routine is called too many times( interrupt state is "GPIO_PIN_INTR_POSEDGE", so after pressing a button, only events with _gpioState->GPIOState with value 8192 should be posted, not with value 0).

code is as follows:

Code:

#include "osapi.h"
#include "user_interface.h"
#include "driver/uart.h"
#include "user_config.h"
#include "eagle_soc.h"
#include "ets_sys.h"
#include "gpio.h"
#include "mem.h"


//static volatile os_timer_t tmrSstart;
//static uint32_t m_Counter = 0;
static bool m_GPIO14 = false;

os_event_t user_procTaskQueue[user_procTaskQueueLen];

//Main code function
static void ICACHE_FLASH_ATTR
loop(os_event_t *events)
{
   os_printf("Task sig=%u, par=%u!\r\n",events->sig, events->par);

   GPIOState * _gpioState = (GPIOState *)(events->par);
   if(_gpioState->GPIOState > 0){
      m_GPIO14 = !m_GPIO14;
      GPIO_OUTPUT_SET(14, m_GPIO14);
      os_printf("GPIO14 set to %u\r\n",  m_GPIO14);
   }

   os_printf("Task executed and memory disposed, RTC=%u, GPIO=%u!\r\n", _gpioState->RtcTime, _gpioState->GPIOState);
   os_free(_gpioState);
}

// GPIO interrupt handler:store local data and start task
static void ICACHE_FLASH_ATTR
iw_GPIO_handler(int8_t key){
   uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   uint32_t rtc_now = system_get_rtc_time();

   GPIOState * _gpioState = (GPIOState *)os_zalloc(sizeof(GPIOState));

   _gpioState->GPIOState = gpio_status;
   _gpioState->RtcTime = rtc_now;

   // activate task
   if (!system_os_post(user_procTaskPrio, 0, (uint32_t)_gpioState)){
      os_free(_gpioState);
      os_printf("Task \"post\" failed\r\n");
   } else
      os_printf("Task \"post\" succeed, RTC=%u, GPIO=%u\r\n", rtc_now, gpio_status);

   // set last interrupt state
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
}



//Init function
void ICACHE_FLASH_ATTR
user_init()
{
   uart_init(BIT_RATE_115200, BIT_RATE_115200);
   os_delay_us(1000);

   uart0_sendStr("Start!\r\n");
   
   //Start os task
   system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);


   // set interrupt routine
   // start first run with timer(otherwise doesn't work?)
   ETS_GPIO_INTR_DISABLE();

   // GPIO12 interrupt handler
   ETS_GPIO_INTR_ATTACH(iw_GPIO_handler, 12);

   // pin 13 setup
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); // select pin to GPIO 13 mode
   GPIO_DIS_OUTPUT(13); // set pin to "input" mode
   PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTCK_U); // disable pullodwn
   PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); // pull - up pin

   // pin 14 setup
   // low output
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); // select pin to GPIO 14 mode
   PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U);
   PIN_PULLDWN_EN(PERIPHS_IO_MUX_MTMS_U);

   //gpio_output_set( BIT14, 0, BIT14, 0 );
   GPIO_OUTPUT_SET(14, 0);

   // interrupt on GPIO 13
   gpio_pin_intr_state_set(GPIO_ID_PIN(13), GPIO_PIN_INTR_POSEDGE); // | GPIO_PIN_INTR_NEGEDGE); // Interrupt on any GPIO13 edge
   gpio_pin_intr_state_set(GPIO_ID_PIN(14), GPIO_PIN_INTR_DISABLE);

   // reset interrupt status
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(13));
   // Enable gpio interrupts
   ETS_GPIO_INTR_ENABLE();

}




Hi FrenkR,

Sorry for the delay , finally I find some time to review your question.

I think your question is why the io interrupt trigger several times even the interrupt status register is 0.

I can just tell you how to solve this problem: to clear the interrupt status once you read it out.

Code:

iw_GPIO_handler(int8_t key){
   uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   uint32_t rtc_now = system_get_rtc_time();
      GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
........

I tried your code but the compiler returns an error.
void.png


So I change the test code :

Code:

#include "osapi.h"
#include "user_interface.h"
#include "driver/uart.h"
#include "user_config.h"
#include "eagle_soc.h"
#include "ets_sys.h"
#include "gpio.h"
#include "mem.h"


//static volatile os_timer_t tmrSstart;
//static uint32_t m_Counter = 0;
static bool m_GPIO14 = false;
#define user_procTaskQueueLen  10
#define user_procTaskPrio 2
os_event_t user_procTaskQueue[user_procTaskQueueLen];

//static void ICACHE_FLASH_ATTR loop(os_event_t *events);

  //system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);


//Main code function
static void ICACHE_FLASH_ATTR
loop(os_event_t *events)
{
   os_printf("Task sig=%u, par=%u!\r\n",events->sig, events->par);

}

// GPIO interrupt handler:store local data and start task
static void ICACHE_FLASH_ATTR
iw_GPIO_handler(int8_t key){
   uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   uint32_t rtc_now = system_get_rtc_time();
      GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);


   // activate task
  // if (!system_os_post(user_procTaskPrio, 0, (uint32_t)gpio_status)){
      //os_free(_gpioState);
    //  os_printf("Task \"post\" failed\r\n");
  // } else
    //  os_printf("Task \"post\" succeed, RTC=%u, GPIO=%u\r\n", rtc_now, gpio_status);


   system_os_post(user_procTaskPrio, 0, (uint32_t)gpio_status);
   os_printf("Task \"post\" succeed, RTC=%u, GPIO=%u\r\n", rtc_now, gpio_status);
   // set last interrupt state

}



//Init function
void ICACHE_FLASH_ATTR
user_init()
{
   uart_init(74880, 74880);
   os_delay_us(1000);

   os_printf("Start!\r\n");
   
   //Start os task
   system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);


   // set interrupt routine
   // start first run with timer(otherwise doesn't work?)
   ETS_GPIO_INTR_DISABLE();

   // GPIO12 interrupt handler
   ETS_GPIO_INTR_ATTACH(iw_GPIO_handler, 12);

   // pin 13 setup
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); // select pin to GPIO 13 mode
   GPIO_DIS_OUTPUT(13); // set pin to "input" mode
   PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTCK_U); // disable pullodwn
   PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); // pull - up pin

   // pin 14 setup
   // low output
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); // select pin to GPIO 14 mode
   PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U);
   PIN_PULLDWN_EN(PERIPHS_IO_MUX_MTMS_U);

   //gpio_output_set( BIT14, 0, BIT14, 0 );
   GPIO_OUTPUT_SET(14, 0);

   // interrupt on GPIO 13
   gpio_pin_intr_state_set(GPIO_ID_PIN(13), GPIO_PIN_INTR_POSEDGE); // | GPIO_PIN_INTR_NEGEDGE); // Interrupt on any GPIO13 edge
   gpio_pin_intr_state_set(GPIO_ID_PIN(14), GPIO_PIN_INTR_DISABLE);

   // reset interrupt status
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(13));
   // Enable gpio interrupts
   ETS_GPIO_INTR_ENABLE();

}


And the log is always 8192 :

Code:

Task sig=0, par=8192!
Task sig=0, par=8192!
Task "post" succeed, RTC=78107212, GPIO=8192
Task "post" succeed, RTC=78107239, GPIO=8192
Task "post" succeed, RTC=78107263, GPIO=8192
 sig=0, par=8192!
Task sig=0, par=8192!
Task sig=0, par=8192!
Task "post" succeed, RTC=78190765, GPIO=8192
Task "post" succeed, RTC=78190791, GPIO=8192
Task sig=0, par=8192!
Task sig=0, par=8192!
Task "post" succeed, RTC=78220619, GPIO=8192
Task "post" succeed, RTC=78220643, GPIO=8192
Task sig=0, par=8192!
Task sig=0, par=8192!

Statistics: Posted by costaud — Mon Jan 12, 2015 12:25 pm


]]>
2015-01-10T19:08:58+08:00 2015-01-10T19:08:58+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=472#p472 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]> Statistics: Posted by FrenkR — Sat Jan 10, 2015 7:08 pm


]]>
2015-01-09T15:29:51+08:00 2015-01-09T15:29:51+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=466#p466 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]> have a try.

Code:

// GPIO interrupt handler:store local data and start task
static void ICACHE_FLASH_ATTR
iw_GPIO_handler(int8_t key){
   uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   uint32_t rtc_now = system_get_rtc_time();

   if (gpio_status & BIT(13)) {
   GPIOState * _gpioState = (GPIOState *)os_zalloc(sizeof(GPIOState));

   _gpioState->GPIOState = gpio_status;
   _gpioState->RtcTime = rtc_now;

   // activate task
   if (!system_os_post(user_procTaskPrio, 0, (uint32_t)_gpioState)){
      os_free(_gpioState);
      os_printf("Task \"post\" failed\r\n");
   } else
      os_printf("Task \"post\" succeed, RTC=%u, GPIO=%u\r\n", rtc_now, gpio_status);

   // set last interrupt state
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(13));
   }
}

Statistics: Posted by jackon — Fri Jan 09, 2015 3:29 pm


]]>
2015-01-05T19:23:15+08:00 2015-01-05T19:23:15+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=445#p445 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]>
As you can see, there is a GPIO trigger is defined only as GPIO_PIN_INTR_POSEDGE on a pin GPIO13. So, regardless "contact bounce" in GPIO14, trigger should not be raised in any way.
I also think that "gpio_pin_intr_state_set" doesn't work as is defined.

This is tested on ESP-03, SDK 0.9.5.
Rgds,
Frenk

Statistics: Posted by FrenkR — Mon Jan 05, 2015 7:23 pm


]]>
2015-01-05T18:06:35+08:00 2015-01-05T18:06:35+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=444#p444 <![CDATA[Re: Changing GPIO inside task with GPIO interrupts bug?]]> Statistics: Posted by ESP_Sprite — Mon Jan 05, 2015 6:06 pm


]]>
2015-01-02T01:29:44+08:00 2015-01-02T01:29:44+08:00 https://bbs.espressif.com:443/viewtopic.php?t=119&p=417#p417 <![CDATA[Changing GPIO inside task with GPIO interrupts bug?]]>

Code:

rst cause:4, boot mode:(1,7)
wdt reset

Also interrupt routine is called too many times( interrupt state is "GPIO_PIN_INTR_POSEDGE", so after pressing a button, only events with _gpioState->GPIOState with value 8192 should be posted, not with value 0).

code is as follows:

Code:

#include "osapi.h"
#include "user_interface.h"
#include "driver/uart.h"
#include "user_config.h"
#include "eagle_soc.h"
#include "ets_sys.h"
#include "gpio.h"
#include "mem.h"


//static volatile os_timer_t tmrSstart;
//static uint32_t m_Counter = 0;
static bool m_GPIO14 = false;

os_event_t user_procTaskQueue[user_procTaskQueueLen];

//Main code function
static void ICACHE_FLASH_ATTR
loop(os_event_t *events)
{
   os_printf("Task sig=%u, par=%u!\r\n",events->sig, events->par);

   GPIOState * _gpioState = (GPIOState *)(events->par);
   if(_gpioState->GPIOState > 0){
      m_GPIO14 = !m_GPIO14;
      GPIO_OUTPUT_SET(14, m_GPIO14);
      os_printf("GPIO14 set to %u\r\n",  m_GPIO14);
   }

   os_printf("Task executed and memory disposed, RTC=%u, GPIO=%u!\r\n", _gpioState->RtcTime, _gpioState->GPIOState);
   os_free(_gpioState);
}

// GPIO interrupt handler:store local data and start task
static void ICACHE_FLASH_ATTR
iw_GPIO_handler(int8_t key){
   uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   uint32_t rtc_now = system_get_rtc_time();

   GPIOState * _gpioState = (GPIOState *)os_zalloc(sizeof(GPIOState));

   _gpioState->GPIOState = gpio_status;
   _gpioState->RtcTime = rtc_now;

   // activate task
   if (!system_os_post(user_procTaskPrio, 0, (uint32_t)_gpioState)){
      os_free(_gpioState);
      os_printf("Task \"post\" failed\r\n");
   } else
      os_printf("Task \"post\" succeed, RTC=%u, GPIO=%u\r\n", rtc_now, gpio_status);

   // set last interrupt state
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
}



//Init function
void ICACHE_FLASH_ATTR
user_init()
{
   uart_init(BIT_RATE_115200, BIT_RATE_115200);
   os_delay_us(1000);

   uart0_sendStr("Start!\r\n");
   
   //Start os task
   system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);


   // set interrupt routine
   // start first run with timer(otherwise doesn't work?)
   ETS_GPIO_INTR_DISABLE();

   // GPIO12 interrupt handler
   ETS_GPIO_INTR_ATTACH(iw_GPIO_handler, 12);

   // pin 13 setup
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); // select pin to GPIO 13 mode
   GPIO_DIS_OUTPUT(13); // set pin to "input" mode
   PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTCK_U); // disable pullodwn
   PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); // pull - up pin

   // pin 14 setup
   // low output
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); // select pin to GPIO 14 mode
   PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U);
   PIN_PULLDWN_EN(PERIPHS_IO_MUX_MTMS_U);

   //gpio_output_set( BIT14, 0, BIT14, 0 );
   GPIO_OUTPUT_SET(14, 0);

   // interrupt on GPIO 13
   gpio_pin_intr_state_set(GPIO_ID_PIN(13), GPIO_PIN_INTR_POSEDGE); // | GPIO_PIN_INTR_NEGEDGE); // Interrupt on any GPIO13 edge
   gpio_pin_intr_state_set(GPIO_ID_PIN(14), GPIO_PIN_INTR_DISABLE);

   // reset interrupt status
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(13));
   // Enable gpio interrupts
   ETS_GPIO_INTR_ENABLE();

}

Statistics: Posted by FrenkR — Fri Jan 02, 2015 1:29 am


]]>