Software interrupt on nRF52832

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
User avatar
chrizztus
Posts: 4
Joined: Thu Feb 23, 2017 3:59 pm

Software interrupt on nRF52832

Postby chrizztus » Wed Mar 08, 2017 9:44 am

Hi,
for a nordic based pcb I'd like to implement micropython callbacks to be triggered once a button was pressed/released.
Similar to the stmhal hardware interrupt in usrsw.c, I'd like to register a button callback in micropython which can be triggered from a software interrupt coming from nordics button driver implementation where I can register several function pointers that will be called on (debounced) short/long pressed/released events.
Since I'm quiet new to micropython I'd appreciate if someone can give me a hint if it's possible to pass function pointers from a micropython module to the button dirver implementation in order to trigger the python callback function.

Best
Christian

User avatar
dhylands
Posts: 2387
Joined: Mon Jan 06, 2014 6:08 pm
Location: Shuswap, BC, Canada
Contact:

Re: Software interrupt on nRF52832

Postby dhylands » Wed Mar 08, 2017 8:28 pm


User avatar
chrizztus
Posts: 4
Joined: Thu Feb 23, 2017 3:59 pm

Re: Software interrupt on nRF52832

Postby chrizztus » Tue Mar 21, 2017 1:43 pm

Hey,
thanks for your support and the example code. I meanwhile got it working so far.
Now I'm facing another issue which might be related to the garbage collector or maybe not. The problem occurs when I'm trying to increment a global variable within a C callback function. I can read and print the value of that variable but once I start writing to it I get the python error: "NameError:"
This is how the C function looks like:
[code]
void ext_button_released_callback(uint8_t button_id, bool long_press)
{
pb_button_obj_t *self = MP_STATE_PORT(pb_button_objects)[button_id];
if(mp_const_none != self->callback)
{
gc_lock();
nlr_buf_t nlr;
if(0 == nlr_push(&nlr))
{
mp_call_function_1(self->callback,mp_obj_new_bool(long_press));
nlr_pop();
}
else
{
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
}
}
[/code]
Is it somehow possible to modify a global var within a callback function?
Christian

PS: Sorry for the bad formatting. Obviously BBCode is not enabled for my account.

User avatar
dhylands
Posts: 2387
Joined: Mon Jan 06, 2014 6:08 pm
Location: Shuswap, BC, Canada
Contact:

Re: Software interrupt on nRF52832

Postby dhylands » Tue Mar 21, 2017 8:16 pm

The formatting will automagically start to work for you after you have enough posts to no longer require moderation.

I don't see any code trying to increment a global. Are you trying to increment a C global? or a python global?

Are you getting the NameError from within the callback? Can you share your python code?

User avatar
chrizztus
Posts: 4
Joined: Thu Feb 23, 2017 3:59 pm

Re: Software interrupt on nRF52832

Postby chrizztus » Wed Mar 22, 2017 8:21 am

Sorry for the lack of information. What I'm trying to do is to increase/decrease the duty time for a LED pwm.
For this I first create an instance of the button and the LED and register a callback as follows:

Code: Select all

import pb
#instantiatte led and buttons
red = pb.LED(0)
record = pb.BUTTON(2)
duty=50

#button callback function
def record_pressed(long_press):
   #printing the duty works well
   print(duty)
   #changing the duty cycle gives error
   duty = (duty + 5) % 100
   #set the new duty for red LED
   red.brightness(duty)

red.callback(record_pressed)

When I comment the line "duty = (duty + 5) % 100" in the callback function everything works. The duty value is printed and the led value is set. Once I uncomment it I get the following error:

Code: Select all

>>> NameError:

For sake of readablity I'll attach the C callback function that'll be called on pushing a button:

Code: Select all

void ext_button_released_callback(uint8_t button_id, bool long_press)
{
  pb_button_obj_t *self = MP_STATE_PORT(pb_button_objects)[button_id];
  if(mp_const_none != self->callback)
  {
    gc_lock();
    nlr_buf_t nlr;
    if(0 == nlr_push(&nlr))
    {
      mp_call_function_1(self->callback,mp_obj_new_bool(long_press));
      nlr_pop();
    }
    else
    {
      mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
    }
    gc_unlock();
  }
}

Maybe there is something wrong/missing here. I recycled it from stmhal/timer.c implementation.

User avatar
pythoncoder
Posts: 1639
Joined: Fri Jul 18, 2014 8:01 am

Re: Software interrupt on nRF52832

Postby pythoncoder » Wed Mar 22, 2017 8:59 am

You need

Code: Select all

def record_pressed(long_press):
   global duty

If you assign to a variable in a Python function, and it is not declared as global, Python creates it as a local variable. However your code requires the value to be read, so you get "NameError: local variable referenced before assignment".

Note that a global declaration is not needed if you only intend to read a global variable. If Python fails to find a name in the local namespace it then looks in global.

This is a perennial source of confusion to people new to Python.
Peter Hinch

User avatar
chrizztus
Posts: 4
Joined: Thu Feb 23, 2017 3:59 pm

Re: Software interrupt on nRF52832

Postby chrizztus » Wed Mar 22, 2017 2:04 pm

pythoncoder wrote:You need
However your code requires the value to be read, so you get "NameError: local variable referenced before assignment".

Note that a global declaration is not needed if you only intend to read a global variable. If Python fails to find a name in the local namespace it then looks in global.

This is a perennial source of confusion to people new to Python.

Thanks Peter,
except a few (slight) contacts with python I'm learning python by implementing the modules needed for my custom board ;)
Although I might have used the keyword in the past, I couldn't assign the error since it only says "NameError:" without the meaningful description you pointed out. It would have helped me a lot.
Nevertheless with your suggestion the code is working and I don't need to debug any further. Thank you for that.
Best
Christian

User avatar
pythoncoder
Posts: 1639
Joined: Fri Jul 18, 2014 8:01 am

Re: Software interrupt on nRF52832

Postby pythoncoder » Thu Mar 23, 2017 7:15 am

chrizztus wrote:... I couldn't assign the error since it only says "NameError:" without the meaningful description you pointed out. It would have helped me a lot...
Error reporting on the ESP8266 still leaves a lot to be desired and it sounds like the nRF52832 has the same problem. It is confusing. On other MicroPython platforms you get the full message.
Peter Hinch


Return to “Other Boards”

Who is online

Users browsing this forum: No registered users and 1 guest