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.
Post Reply
User avatar
chrizztus
Posts: 16
Joined: Thu Feb 23, 2017 3:59 pm

Software interrupt on nRF52832

Post by 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: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Software interrupt on nRF52832

Post by dhylands » Wed Mar 08, 2017 8:28 pm


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

Re: Software interrupt on nRF52832

Post by 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: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Software interrupt on nRF52832

Post by 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: 16
Joined: Thu Feb 23, 2017 3:59 pm

Re: Software interrupt on nRF52832

Post by 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: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Software interrupt on nRF52832

Post by 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
Index to my micropython libraries.

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

Re: Software interrupt on nRF52832

Post by 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: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Software interrupt on nRF52832

Post by 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
Index to my micropython libraries.

Post Reply