waiting for an interrupt flag to be set

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

waiting for an interrupt flag to be set

Post by devnull » Tue Nov 05, 2019 3:19 am

This seems to work erratically for me.

In an ISR, I set a boolean Flag, i.e. self.connected, and then in a function I tight-loop waiting for this flag to be set:

Code: Select all

While not self.connected:
   pass
do something when connected
Now sometimes this works, and sometimes it does not, is there any way to do this reliably ??

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: waiting for an interrupt flag to be set

Post by devnull » Tue Nov 05, 2019 3:51 am

If the function is reading the value of self.connected inside the tight loop when self.connected is being modified by the interrupt will this cause problems ??

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: waiting for an interrupt flag to be set

Post by jimmo » Tue Nov 05, 2019 4:09 am

Can you share more example code?

What sort of interrupt? e.g. hard (stm32 pin), soft (esp32 pin, BLE, etc)?

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: waiting for an interrupt flag to be set

Post by devnull » Tue Nov 05, 2019 4:13 am

Well Jimmo, in this case it is part of the Peripheral class that you kindly provided me with:

Code: Select all

  
 Class Peripheral:
  ... 
  def connect(self,mswait=2000):
    if not self._connected:
      self._central._connecting_peripherals[(self._addr_type, self._addr)] = self
      self._central._ble.gap_connect(self._addr_type, self._addr)
    now = time.ticks_ms() 
    while time.ticks_diff(time.ticks_ms(),now) < mswait:
      if self._connected: break
    return self._connected  

  ## Central Interrupt - Called
  def connected(self):
    self._connected = True
What I am trying to achieve is an async connect !

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: waiting for an interrupt flag to be set

Post by devnull » Tue Nov 05, 2019 4:29 am

Now I am thinking that it might be that the device is not connecting and that it's nothing to do with the interrupt, but generically speaking if you modify a variable in an ISR and then in a loop read the value, could this be an issue ??

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: waiting for an interrupt flag to be set

Post by jimmo » Tue Nov 05, 2019 9:08 am

devnull wrote:
Tue Nov 05, 2019 4:13 am
What I am trying to achieve is an async connect !
Technically that's a synchronous connect, but yes, definitely useful!

I would like to make a properly asyncio-based wrapper around the low-level API, so you can have the best of both worlds.

Anyway, what you're doing is fine -- modifying a value from an ISR and reading it outside the ISR is fine - and is a very common thing to do.

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: waiting for an interrupt flag to be set

Post by devnull » Tue Nov 05, 2019 11:17 pm

@jimmo - I have just discovered on the Pyboard D, that sometimes it receives a disconnect interrupt for connection handle 65535, even though a connection for this handle was never opened.

It then appears that the next connect attempt will fail.

Any idea what this is ???

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: waiting for an interrupt flag to be set

Post by devnull » Wed Nov 06, 2019 9:19 am

I need for this to be bullet proof as it will be running un-manned.

I am getting a lot of disconnect interrupts with handle 65535 and this then appears to kill the next connection.

This loop is simply stress testing, and I get the 65535 handle VERY frequently !

Code: Select all

h1 = j.Dev(b"\xcb\xd0\xc5\x0c'\xbd")
import time
while True:
	h1.connect()
	time.sleep(1)
	h1.disconnect()
	time.sleep(1)
Trap the 65535 handle...

Code: Select all

    if event == _IRQ_PERIPHERAL_DISCONNECT:
      if data[0] == 65535: 
        return print('@@@ERROR')

Code: Select all

connected 64
True
True
disconnected 64
connected 64
True
True
disconnected 64
connected 64
True
True
disconnected 64
@@@ERROR
False
False
connected 64
True
True
disconnected 64
connected 64

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: waiting for an interrupt flag to be set

Post by jimmo » Wed Nov 06, 2019 9:23 am

Ok thanks for the details, I will investigate!

User avatar
devnull
Posts: 473
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: waiting for an interrupt flag to be set

Post by devnull » Wed Nov 06, 2019 9:49 am

Jimmo, I can work around this by setting a error flag and if the flag is set and connection fails, then clear the flag and retry the connection.

This prevents the connection failure but wastes time attempting the connection twice, and it only appears to happen on the first connection after the error.

I think that 65535 might be the handle that is reported, when a response is received from a device that was connected in a previous session but no longer has an active connection in the current session ?.

It would be useful if you could query BLE for a list of it's connection handles :-)

Post Reply