PinAF objects and code smells

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
mwm
Posts: 36
Joined: Wed Aug 09, 2017 3:52 pm

PinAF objects and code smells

Post by mwm » Tue Aug 15, 2017 11:45 pm

I started with this issues on Github, but apparently this needs to be discussed on the forum, so here we go.

I posted it as an issue because there's a documented method that doesn't exist. Clearly, a bug in either the objects or the documentation.

Further, to me objects that aren't equal but have no features that are different are a code (well, type) smell for a number of reasons. But in this case, I think there's a good reason for me to be able to tell them apart - I'd like to be able to see the string that's in the _af file.

In my case, I'm wanting an easy way to do PWM. I know there's a module that gets a lot of use, but the versions I found all had a dictionary embedded in it that was wrong for my board, with no hints as to how to create it.I figured it would be easier to write a PWM library that didn't depend on creating that dictionary by hand (I was right, BTW - building micropython creates af_pins.py, which can be used as is).

In researching that, I found the PinAF objects. Those would be perfect for this - if I could figure out which of the various TIM2_* functions I had. You want PWM on a Pin? Call pin.af_list() and look for the one whose __str__() is of the form TIM#_CH#. As it is, I can use them to figure out if a pin is used by any timer, or a specific timer. But without knowing if it's _CH#, or what channel it's for, they aren't sufficient.

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

Re: PinAF objects and code smells

Post by dhylands » Wed Aug 16, 2017 12:30 am

Right - we decided not to include the contents of pins_af.py in the flash because we didn't have many use cases for it, and it would use a bunch of flash.

Personally, I like to use pins_af.py along with the functions in the examples/pins.py function. This allows me to see which pins have been configured which way.

The data to figure out whether a particular pin has a particular function is available at the C level. We use this to figure what the AF on a particular pin is for say SPI.

An example of this can be found here:
https://github.com/micropython/micropyt ... spi.c#L332
and probably more relevant, the pin_find_af function:
https://github.com/micropython/micropyt ... pins.c#L55

The Pin and PinAF data structures are currently all generated programmatically. You can look at the underlying data by looking at the pins_BOARDNAME.c in the build-BOARDNAME directory. A snippet from the PYBV11 board looks like this:

Code: Select all

const pin_af_obj_t pin_A2_af[] = {
  AF( 1, TIM     ,  2, CH3       , TIM2    ), // TIM2_CH3
  AF( 2, TIM     ,  5, CH3       , TIM5    ), // TIM5_CH3
  AF( 3, TIM     ,  9, CH1       , TIM9    ), // TIM9_CH1
#if defined(MICROPY_HW_UART2_TX)
  AF( 7, USART   ,  2, TX        , USART2  ), // USART2_TX
#endif
  //(11, ETH     ,  0, MDIO      , ETH     ), // ETH_MDIO
  //(15, EVENTOUT,  0,           , EVENTOUT), // EVENTOUT
};

const pin_obj_t pin_A2 = PIN(A, 2, pin_A2_af, PIN_ADC1 | PIN_ADC2 | PIN_ADC3, 2);
I think what you're wanting is some way of querying this information from python (rather than C), perhaps by exposing the pin_find_af function along with some appropriate constants?

mwm
Posts: 36
Joined: Wed Aug 09, 2017 3:52 pm

Re: PinAF objects and code smells

Post by mwm » Wed Aug 16, 2017 2:20 am

Yeah, wanting access to that information from Python is the most important issue here. If I could get it without having to include pins_af.py, that would be great. Just out of curiosity, do you know how much bigger pins_af.py is than the dictionary used in those modules?

Second is the __str__ method. It should either exist, or be removed from the documentation.

I'm confused about what the PinAF objects are used for. I quick search doesn't turn up any functions that accept them as arguments. Nothing in the code base seems to use the class. It might make sense for them to use the default Python equality test, but it's hard to say without knowing what their intended use is. If it's just to provide information to the programmer, using them as the hook for providing the access in the first paragraph might make sense.

Post Reply