pimoroni / i2cdevice-python

Domain-specific language for describing smbus/i2c register maps
MIT License
26 stars 14 forks source link

Register class makes it impossible to handover parameter fields #9

Closed PaulskPt closed 3 years ago

PaulskPt commented 3 years ago

I think that /i2device/ __ini__.py, line 124, should read: 'self.fields = fields' instead of: 'self.fields = {}' because with this command it makes it impossible to handover the value of the parameter 'fields'. After I changed this, I received a "TypeError: 'BitField' object is not iterable" (in line 127). I am trying to investigate/solve that.

Gadgetoid commented 3 years ago

Do you have a usage example that shows what's happening?

The value fields should be an iterable, ie: a list or tuple passed into the register. In the case of a single field you can use (Field(), ) to indicate a tuple with one element.

This is converted into a dict right below the line you mention:

        self.fields = {}

        for field in fields:
            self.fields[field.name] = field

https://github.com/pimoroni/i2cdevice-python/blob/31640909309406bb7b8d8df0a1c1006d1ef88f6b/library/i2cdevice/__init__.py#L126

A better fix in your case would be to check and see if fields is actually iterable, or just a single instance of BitField or another field type and convert it into a list of one element so the subsequent code will succeed.

Correct usage, noting the plural "fields", however is:

Register(fields=(BitField(), ))

Probably wouldn't hurt to have some docstrings or a better error for this.

PaulskPt commented 3 years ago

I think I interpreted wrong. I close the issue.

PaulskPt commented 3 years ago

Afterburner: can I ask why those three classes 'class Adapter', 'LookupAdapter' and ' U16ByteSwapAdapter' are in a separate file 'adapter.py' and not in __init__.py ? Thank you.

PaulskPt commented 3 years ago

Excuse me for not (yet) answering. I am trying to port rv3028 (that uses i2device) to use with a RPi Pico. I own a Pimoroni 'pico explorer pack' with a rv3028 rtc breakout, a rgb rotary encoder breakout (and some other breakouts). Classs rv3028 uses constructions like: 'Register('CONTROL_1', 0x0F, fields=( BitField('value', 0xFF), BitField('timer_repeat', 0b10000000), BitField('weekday_date_alarm', 0b00100000), BitField('update_interrupt', 0b00010000), BitField('eeprom_memory_refresh_disable', 0b00001000), BitField('periodic_countdown_timer_enable', 0b00000100), BitField('timer_frequency_selection', 0b00000011, adapter=LookupAdapter( {'4036Hz': 0b00, # 214.14us '63Hz': 0b01, # 15.625ms '1Hz': 0b10, # 1s '0.016Hz': 0b11})) # 60s )),'

Gadgetoid commented 3 years ago

We have a C++ Pico driver for RV3028 which might be a better reference - https://github.com/pimoroni/pimoroni-pico/tree/main/drivers/rv3028 - this will get baked into our MicroPython .uf2 eventually.

i2cdevice's constructs are just a way to describe the register bit values and what they do- they may prove to be a better or worse reference than the datasheet.

If you're working in Python we did have some success making i2cdevice work there, but YMMV.

PaulskPt commented 3 years ago

Thank you! I am not that good yet in applying c++ for the RPi Pico. I didn't study yet how to compile and build c++ projects. With saying, I quote: ' this will get baked into our MicroPython .uf2 eventually.' means that it is not sure yet that a driver for the rv3028 will get baked into the Pimoroni-Pico firmware? Btw. I saw on: https://docs.micropython.org/en/latest/library/pyb.RTC.html about 'rtc = pyb.RTC()'. You think it is possible to port that to make it useable for the rv3028 breakout to use it with a RPi Pico? (Excuse me, maybe this is a question to post in the Discord group).