Update pinmap design document

Update the pinmap design document to reflect the current design and to
match the design document template.
pull/9690/head
Russ Butler 2019-02-12 15:20:29 -06:00
parent 50be53b853
commit 73403b02bc
1 changed files with 48 additions and 72 deletions

View File

@ -1,6 +1,6 @@
# HAL PinMap
# HAL PinMap design document
<!-- toc -->
# Table of contents
- [Description](#Description)
- [Motivation](#Motivation)
@ -10,98 +10,74 @@
<!-- tocstop -->
## Description
# Introduction
Adds board introspection capabilities and tools.
These tools will help designing better tests for the HAL.
## Motivation
### Overview and background
At the time being, drivers are only tested on a single "default" peripheral. However, some target feature the same peripheral through different blocks' implementations for example the SPI may be provided on a single MCU by its USART, QSPI and SSP peripherals.
To ensure that the driver's implementation is valid for all these peripherals we want the CI to run the test set on each peripheral using at least one set of pin determined at run time (pin may eventually picked randomly).
## Requirements
### Requirements and assumptions
1. We want to list all pins for a function on a peripheral.
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.
4. We want a printable name for each form factor pin and a method to get that name.
5. We want a list of the reserved pins that cannot be tested.
6. We want to select a duplicate-free set a pin from a set of PinMap.
Any of the list mentioned above may be empty if none match the criteria.
## Design choices
# System architecture and high-level design
These requirements do not impact the current API and thus they can all be implemented as an extension to the existing API.
It is proposed to introduce the following elements :
- `DEVICE_PIN_EXTENDED_SUPPORT` A `device_has` flag indicating the implementation of this extension.
- 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,
PINMAP_FORM_FACTOR_ARDUINO_DUE,
PINMAP_FORM_FACTOR_NXP_FRDM,
PINMAP_FORM_FACTOR_ST_MORPHO,
PINMAP_FORM_FACTOR_MTB,
} pinmap_form_factor_t;
### Pinmap
/// returns a static NC terminated array of pins (or NULL if unsupported).
const PinName *pinmap_form_factor_pins(pinmap_form_factor_t form_factor);
/// 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);
```
- These generic function make use of the existing API to answer requirements 1, 2 and 6.
```c
/// Returns the `n`'th pin supporting the `peripheral` in the `map`.
PinName pinmap_find_peripheral_pin(const PinMap *map, int peripheral, uint32_t n);
All HAL APIs which use pins have functions to get the corresponding pin maps. These functions return a `PinMap` array with each entry containing a pin name, a peripheral and a function. The end of the pin map array is indicated by the presence of a NC pin. Below is an example implementation of the function to get the serial tx pinmap:
/// 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,
const PinName *blacklist, int per);
```C
const PinMap PinMap_UART_TX[] = {
{P0_19, UART_0, 1},
{P1_13, UART_0, 3},
{P1_27, UART_0, 2},
{ NC , NC , 0}
};
const PinMap *serial_tx_pinmap()
{
return PinMap_UART_TX;
}
```
/// Verifies that `pin` is in `list`.
bool pinlist_has_pin(const PinName *list, PinName pin);
Targets which don't make use of a pinmap, such as ones with peripherals that can be connected to any pin, must still define pinmaps as these are needed for testing. For these devices the pinmap does not need to be comprehensive. Instead it should list a representative sample of pins and peripherals so they can be tested appropriately.
/// Applies pinmap_find_peripheral_pin to each map in maps ensuring a pin will not be used twice.
/// @param[in] maps A list of pinmap.
/// @param[in] count Number of elements of maps and pins.
/// @param[in] whitelist An NC terminated list of pins.
/// @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,
uint32_t count,
const PinName *whitelist,
const PinName *blacklist,
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).
### Form Factor
For example the SPI api may be extended with :
```c
#ifdef DEVICE_SPI_PIN_EXTENDED_SUPPORT
PinMap *spi_get_mosi_pins(bool as_slave, bool is_half_duplex);
PinMap *spi_get_miso_pins(bool as_slave, bool is_half_duplex);
PinMap *spi_get_clk_pins();
PinMap *spi_get_cs_pins();
#endif
```
A boards form factor determines what can be tested automatically. A board can have one or more form factors, each listed in the `supported_form_factors` entry in targets.json:
and the I²C api with :
```c
#ifdef DEVICE_I2C_PIN_EXTENDED_SUPPORT
PinMap *i2c_get_scl_pins();
PinMap *i2c_get_sda_pins();
#endif
```
```
"supported_form_factors": ["ARDUINO"],
```
The Mbed pinamp code has built in support for common form factors, such as `ARDUINO`. When a known form factor is present in the `supported_form_factors` list then it will be used automatically for testing. Use the target configuration value `default-form-factor` to test a custom form factor or to force the tools to use a given form factor.
## Questions
Use the function `const PinList *pinmap_ff_default_pins(void)` to get the pins of a form factor for testing. Additionally the name of a given form factor pin can be found with the function `const char *pinmap_ff_default_pin_to_string(PinName pin)`.
### Restricted Pins
Some boards have pins which cannot be tested without causing problems elsewhere. One example of this is the serial TX and RX pins used for communication during testing. If these pins are used during a test then communication with the host PC will be lost. To prevent pins like this from being used a target can override the weak function `pinmap_restricted_pins()` to return a pin list containing all target pins which should be skipped during testing. By default this function only includes the TX and RX pins used for communication during testing:
```c
MBED_WEAK const PinList *pinmap_restricted_pins()
{
static const PinName pins[] = {
USBTX, USBRX
};
static const PinList pin_list = {
sizeof(pins) / sizeof(pins[0]),
pins
};
return &pin_list;
}
```