Skip to content

Add RFC for PinMap's extension #8693

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

Closed
wants to merge 6 commits into from
Closed

Add RFC for PinMap's extension #8693

wants to merge 6 commits into from

Conversation

ithinuel
Copy link
Member

@ithinuel ithinuel commented Nov 9, 2018

Description

This proposal adds an extension to PinMap's API.
This will allow advanced test to arbitrarily select a peripheral and configure the pins to test.

Pull request type

[ ] Fix
[ ] Refactor
[ ] Target update
[x] Functionality change
[ ] Docs update
[ ] Test update
[ ] Breaking change

@adbridge
Copy link
Contributor

@ARMmbed/mbed-os-hal @c1728p9 This has been awaiting review for 5 days now , could you please ensure it is looked at asap.

3. We want to list all pins for a form-factor regardless of the function they can provide.
4. We want a printable name for each pin and a method to get that name.
5. We want a list the reserved pins that cannot be tested.
6. We want to select a duplicate-free set a pin from a set of PinMap.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit unclear for me. Do we mean selecting a subset of the given PinMap?

Copy link
Member Author

@ithinuel ithinuel Nov 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us consider this example :

PinMap *maps[] = {
    spi_get_mosi_pins(false),
    spi_get_miso_pins(false),
    spi_get_clk_pins(),
    spi_get_cs_pins()
};
PinName pins[4];

pinmap_find_peripheral_pins(maps,
                           pinmap_form_factor_pins(PINMAP_FORM_FACTOR_ARDUINO_ZERO),
                           pinmap_restricted_pins(),
                           SPI2,
                           pins,
                           4
);

// pins would be :
// pins = { a_pin_from_mosi_pins,
//          a_pin_from_miso_pins,
//          a_pin_from_clk_pins,
//          a_pin_from_cs_pins
// };
//
// None of them being equal.

Copy link
Member

@fkjagodzinski fkjagodzinski Nov 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All clear now. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get that either, I'm assuming you mean "We want to select a duplicate-free set of pins from a set of PinMaps." But I still don't see what that means. Looking at the example doesn't make it clearer and the function is not defined below (unless it's the same as _pin below). What is that for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _bus was used before an update that came on filip's review.

I edited the previous answer to match new most recent PR.
Let me know if you stil have questions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case there? Why do we need that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what the tests will use to pick the pins from the lists.

/// returns an NC terminated array of pins.
const PinName *pinmap_form_factor_pins(pinmap_form_factor_t form_factor);
/// returns an NC terminated array of pins.
const PinName *pinmap_restricted_pins();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably an implementation detail -- should we provide a pinmap_free() function or tell the user to use the generic one?

Or are these supposed to be static, like other arrays fomr PeripheralPins.h?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are indeed supposed to be static.

/// Returns a pin from ((whitelist ∩ map) − blacklist).
/// Typically, whitelist will be the form factor list of pins.
/// The blacklist may be a list of pins already visited and/or tied to another peripheral.
PinName pinmap_find_peripheral_pins(const PinMap *map, const PinList *whitelist,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this fun returns a single PinName I think the plural _pins part of the name could confuse some users. Also do we need both whitelist and blacklist?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I fixed the name of the function.

The ((whitelist ∩ map) − blacklist) operation could be achieve before calling this function but it might be easier to use if it is done internally. you wouldn't have to reimplement it for each tests.

Copy link
Member

@fkjagodzinski fkjagodzinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more questions from me. Has anyone from @ARMmbed/mbed-os-hal anything to add?

@0xc0170 0xc0170 requested review from a team and bulislaw November 20, 2018 09:23
Copy link
Member

@bulislaw bulislaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm missing description of how it is defined in target and what partners are expected to give us and what is "platform" code working on that input.


## Description

This update aims at increasing tests thoroughness by enabling them to check driver's reliability for each pin declared as supporting a peripheral.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is killing me, can we rewrite it in readable way.


## Requirements

1. We want to list all pins for a function on a peripheral.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is eg all SPI MOSI pins?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is all SPI MOSI for SPI1.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be worth saying that in the doc ("for instance, all pins that can be configured as MOSI for SPI1")

2. We want to list all functions a pin can provide.
3. We want to list all pins for a form-factor regardless of the function they can provide.
4. We want a printable name for each pin and a method to get that name.
5. We want a list the reserved pins that cannot be tested.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the -> of

3. We want to list all pins for a form-factor regardless of the function they can provide.
4. We want a printable name for each pin and a method to get that name.
5. We want a list the reserved pins that cannot be tested.
6. We want to select a duplicate-free set a pin from a set of PinMap.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get that either, I'm assuming you mean "We want to select a duplicate-free set of pins from a set of PinMaps." But I still don't see what that means. Looking at the example doesn't make it clearer and the function is not defined below (unless it's the same as _pin below). What is that for?

- The following part of the API provides the features needed for requirements 3, 4 and 5
```c
enum pinmap_form_factor_ {
PINMAP_FORM_FACTOR_ARDUINO_ZERO,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that growable? If yes, what's the impact?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the impact is null as pinmap_form_factor_pins return NULL for unsupported/unknown form factors.

/// Returns a pin from ((whitelist ∩ map) − blacklist).
/// Typically, whitelist will be the form factor list of pins.
/// The blacklist may be a list of pins already visited and/or tied to another peripheral.
PinName pinmap_find_peripheral_pin(const PinMap *map, const PinName *whitelist,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that's a helper function that works on "sets" rather than something partners will need to do.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed these functions are not platform dependant.

uint32_t per,
PinName *pins);
```
- Additionally to these requirements any peripheral API must expose adequate functions to fetch an NC terminated list of pins associated to each of their their functions. These API extensions shall be gated with a `<PERIPHERAL_NAME>_PIN_EXTENTION` where `<PERIPHERAL_NAME>` is the name of the considered peripheral (`SPI`, `I2C`, `CAN` etc).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need these specific wrappers? If they are not required by the solution why are we mentioning them? That not only adds unnecessary functions, but also pollutes "device_has" even more than it is already.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some device may require specific implementation of the wrapper.
Eg: K66F platform do not have a defined list of MOSI pins and MISO pins that work for both MASTER & SLAVE mode.
It has instead a SOUT and a SIN list of pins that are always respectively output or input.
a spi_get_miso_pins(bool is_slave); would select which pin list to return according to the is_slave argument.

A platform without this requirement would use the default implementation that returns SPI_PinMap_MISO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just treat SPI Master and SPI Salve as two specific features?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would need to be discussed in the appropriate PR when these methods will be introduced.

/// @param[in] blacklist An NC terminated list of pins.
/// @param[in] per A peripheral name.
/// @param[out] pins An array of PinName where the result is stored.
bool pinmap_find_peripheral_pins(const PinMap const **maps,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need pin and pins version of this function? How will you know how big is the out array? Number of elements of maps and pins what does it mean? Is maps and pins parameters need to be the same length?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the _pin only work for a single pinmap and returns a single pin.
In _pins :
maps & pins have the same length/number of elements.
pinmap_find_peripheral_pin is called for each map in maps including the previously returned pin to the black list.
pinmap_find_peripheral_pins returns a valid combination of pins ensuring that a pin does not appear more than once in pins.

These two functions are generic and are not implemented by partners.

@donatieng
Copy link
Contributor

@ARMmbed/mbed-os-maintainers After a chat with @bulislaw, moving the targeted version to 5.12 as we don't need it as part of 5.11 release

@bulislaw
Copy link
Member

We don't need to wait till 5.12, but it's not needed for 5.11.

@cmonr
Copy link
Contributor

cmonr commented Nov 26, 2018

We don't need to wait till 5.12, but it's not needed for 5.11.

@bulislaw Noted.

Marking for now so that we can focus on other PRs appropriately.

Copy link
Contributor

@donatieng donatieng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good first draft but I'm a bit worried about the level of complexity here, both for partners and users - can we simplify a bit?

+1 on adding requirements for partners and how this API will be used.

Some MCUs have some very specific pin mapping features, for instance how would this API deal with SiLabs' crossbar feature?
https://www.silabs.com/documents/public/application-notes/AN671.pdf


## Requirements

1. We want to list all pins for a function on a peripheral.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be worth saying that in the doc ("for instance, all pins that can be configured as MOSI for SPI1")

## Description

Adds board introspection capabilities and tools.
These tools will help designing better tests for the HAL.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this paragraph needs expanding a little bit


## Motivation

At the time being, drivers are only tested on a single "default" peripheral. However, some target features the same peripheral through different IP for example the SPI may be provided on a single MCU by its USART, QSPI and SSP peripherals. To ensure that the driver implementation is valid for all these peripherals we want the CI to assess each pin in at least one pin configuration for each peripheral.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"different IP" feels a bit vague to me - what do you think of "different block implementations" or something like that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"some target features" -> "feature"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"we want the CI to assess each pin in at least one pin configuration for each peripheral" -> pins are not assessed there, I think features are

3. We want to list all pins for a form-factor regardless of the function they can provide.
4. We want a printable name for each pin and a method to get that name.
5. We want a list the reserved pins that cannot be tested.
6. We want to select a duplicate-free set a pin from a set of PinMap.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case there? Why do we need that?

PINMAP_FORM_FACTOR_ARDUINO_DUE,
PINMAP_FORM_FACTOR_NXP_FRDM,
PINMAP_FORM_FACTOR_ST_MORPHO,
PINMAP_FORM_FACTOR_MTB,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should clarify how a partner would contribute to that - also, if you go down to the chip/module level - that's almost one form factor (sometimes more!) per chip/module 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would most probably require the definition of an array per form factor defining which pin are available in this FF.
What do you think would be the more appropriate ?

/// returns a static NC terminated array of pins.
const PinName *pinmap_restricted_pins();
/// returns a null (\0) terminated static character array representing the name of the pin.
const char *pinmap_pin_to_string(PinName pin);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any naming rules?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using the vendor's naming convention ?

uint32_t per,
PinName *pins);
```
- Additionally to these requirements any peripheral API must expose adequate functions to fetch an NC terminated list of pins associated to each of their their functions. These API extensions shall be gated with a `<PERIPHERAL_NAME>_PIN_EXTENTION` where `<PERIPHERAL_NAME>` is the name of the considered peripheral (`SPI`, `I2C`, `CAN` etc).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just treat SPI Master and SPI Salve as two specific features?

@cmonr cmonr dismissed donatieng’s stale review December 21, 2018 03:41

Looks like changes were addressed. Please re-review.

@cmonr
Copy link
Contributor

cmonr commented Dec 21, 2018

@donatieng Please re-review.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 21, 2019

Shall we resume reviewing this RFC ?

@c1728p9
Copy link
Contributor

c1728p9 commented Jan 22, 2019

Pinmap code is ready for review directly in #9449. Would updating this RFC be useful to the review process or would it be easier to review the design only in #9449? If the latter then I'll close this PR.

@ithinuel ithinuel mentioned this pull request Jan 22, 2019
Copy link
Contributor

@SenRamakri SenRamakri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ithinuel - The Pinmap design document looks good, but please follow the design-document template. Note that the template is flexible, so you are not required to fill all the sections if it doesnt apply.

@0xc0170
Copy link
Contributor

0xc0170 commented Feb 11, 2019

Pinmap code is ready for review directly in #9449. Would updating this RFC be useful to the review process or would it be easier to review the design only in #9449? If the latter then I'll close this PR.

What's the status? Pinmap was integrated to master, let us know how to progress here (this should have been integarted first).

@c1728p9
Copy link
Contributor

c1728p9 commented Feb 11, 2019

@0xc0170 I think we should close this. The design document should be a collaboration between architects and engineers. The review and collaboration was done as part of #9449. I don't see a benefit to updating this.

@cmonr
Copy link
Contributor

cmonr commented Feb 11, 2019

@ithinuel Thoughts on @c1728p9 reply?

I didn't notice any comments from you in the referenced PR: #9449

@c1728p9 c1728p9 mentioned this pull request Feb 12, 2019
@c1728p9
Copy link
Contributor

c1728p9 commented Feb 12, 2019

@0xc0170 or @cmonr the content has been updated and moved to #9690. Feel free to close this.

@cmonr cmonr closed this Feb 12, 2019
@cmonr cmonr removed the needs: work label Feb 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants