-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First draft of eveL, the low-level module of the Gameduino bindings #2581
Conversation
…eTek EVE) bindings. [#2578]
Smoke test for the built module:
Also at https://github.com/jamesbowman/py-bteve/blob/master/examples/smoke_eveL.py |
Exclude modeveL-gen.h from Sphinx build
Fix build break because of overflowing small ports
I'm debugging a MicroPython vs CircuitPython difference right now. This causes crashes on CircuitPython. Will update here when I understand more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this first draft! I've replied with a couple high level questions.
shared-bindings/eveL/__init__.c
Outdated
|
||
// #if MICROPY_PY_BUILTINS_EVEL | ||
|
||
//| :mod:`eveL` --- low-level BridgeTek EVE bindings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend calling this _eve
. The _ prefix in Python denotes that it is private and the api may change without warning. Then you can call the high level library eve
.
shared-bindings/eveL/__init__.c
Outdated
} | ||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f); | ||
|
||
STATIC mp_obj_t _cmd(size_t n_args, const mp_obj_t *args) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this different than struct
? It'd be great to separate the implementation of these functions from the definition and arg parsing so that they are better documented. Right now, it is unclear what the _eve
module would contain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- How is this different than
struct
?
The methods in this module (e.g. _vertex2f) align their arguments on bit boundaries, not the byte boundaries used by struct
. Also these methods append the binary commands to an internal buffer, avoiding the overhead of constructing an ephemeral bytes
object for the binary command.
- It'd be great to separate the implementation of these functions from the definition and arg parsing so that they are better documented.
So taking vertex2f
, which currently looks like this:
STATIC mp_obj_t _vertex2f(mp_obj_t self , mp_obj_t a0, mp_obj_t a1) {
int16_t x = (int16_t)(16 * mp_obj_get_float(a0));
int16_t y = (int16_t)(16 * mp_obj_get_float(a1));
C4(self, (0x40000000 | ((x & 32767) << 15) | (y & 32767)));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f);
Then I guess a split would be:
STATIC void vertex2f(mp_obj_t self, int16_x, int16_y) {
C4(self, (0x40000000 | ((x & 32767) << 15) | (y & 32767)));
}
STATIC mp_obj_t _vertex2f(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) {
vertex2f(self,
(int16_t)(16 * mp_obj_get_float(a0)),
(int16_t)(16 * mp_obj_get_float(a1)));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f);
Then vertex2f
is in the business of packing integer bitfields for the hardware.
And _vertex2f
is in the business of arg parsing before handing off to the integer interface.
(And similarly for all the other C methods.)
Is this along the right lines?
- Right now, it is unclear what the _eve module would contain.
Modules eve
and _eve
together contain all the command definitions that are in the hardware datasheet. The split is that _eve
contains the parts that benefit most from being coded in C.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Ok, makes sense to use this for sub-byte packing. Note that
struct
can skip bytes objects withpack_into
where you give it a bytearray. -
Yup, that is on the right track. We then put the arg parsing in shared-bindings and the implementation in shared-modules. shared-bindings can also have inline docs. We name everything verbosely too so it includes the module name (
_eve
in this case). The example implementation function would becommon_hal__eve_vertex2f
. The arg parsing methods can be shorter because they are internal to the object. -
Cool, sounds like the right structure then. It'd be great to document the C implementations for consistency with everything else.
@tannewt thanks for these - I'll get started on them later today. For now I am stuck on what I think is an internals difference between MicroPython and CircuitPython. I wonder if you have any ideas on what might be going on. I'm using this reduced module for testing, which makes a class EVEL with one method, "flush". The problem is that when EVEL is subclassed, the "self" that flush receives is not an EVEL.
Gives:
This seems very strange. The C code for "flush()" now cannot access the private elements of EVEL because it's received a Foo instead. Running the same code on MicroPython behaves as expected: flush() receives the same object that make_new made. From the unix port, same C code with minor tweaks:
The minimal module that shows the problem:
|
Yes, this is a deliberate difference. We want native code to be able to call functions on a subclass. ( |
In fact I can demonstrate the same problem the existing
causes a crash, because the C code for settimeout() got a "self" that is a Again, this works as expected on MicroPython:
|
Aha, that's what I needed. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the split! It's definitely getting closer! Would it be possible to merge all of auto-generated functions into init.c as well? I realize that would make updating a bit more work but it'd be more consistent here. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting really close! Thank you for the doc strings!
|
||
STATIC const mp_rom_map_elem_t mp_module__eve_globals_table[] = { | ||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__eve) }, | ||
{ MP_ROM_QSTR(MP_QSTR__EVE), MP_OBJ_FROM_PTR(&_EVE_type) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd drop the _ on the EVE class since the module name already has it. I'm ok if you'd prefer to keep it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to keep it thanks. The two modules are used like this
from _eve import _EVE
from eve import EVE
class Gameduino(_EVE, EVE):
...
So it's a little more explicit to keep the underscore naming.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you have EVE subclass _EVE instead? I'm a little nervous that the multi-inheritance isn't well tested.
Correct argument order better argument naming fix copypaste bug on C and F arguments
Is this ready for another look? |
Yes, thanks. Comments above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just two comments. Getting very close! I'd love to chat about how we can use _eve for the internal display stuff too. I'd love to see a CircuitPython prompt on a TV via EVE HDMI. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much more readable! Thank you so much!
nice work @jamesbowman ! |
First draft of eveL, the low-level module of the Gameduino (and BridgeTek EVE) bindings.
[#2578]