Skip to content

Commit d59a3b9

Browse files
committed
Add porting guide for explicit pinmap extension
1 parent c67ba6c commit d59a3b9

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<h2 id="explicit-pinmap-port">Explicit Pinmap extension</h2>
2+
3+
The **Explicit Pinmap extension** allows the peripheral configuration (pin/periheral/function) to be explicitly specified in the HAL API function.
4+
5+
### Overview and background
6+
7+
HAL APIs making use of pins take these pins in their constructor and use those pins to lookup which peripheral/function to use. The process of looking up the peripheral/function requires there to be a pinmap table that maps pins to peripherals/functions. This pinmap table takes up ROM which could be saved if the pinmap wasn't used. Explicit pinmap extension provides additional HAL API/constructors which takes pinmap as a parameter where pin/peripheral/function is specified explicitly and there is no need to use the pinmap tables.
8+
9+
Supported peripherals:
10+
 - `PWM`
11+
 - `AnalogIn`
12+
 - `AnalogOut`
13+
 - `SPI`
14+
 - `I2C`
15+
 - `UART`
16+
 - `QSPI`
17+
 - `CAN`
18+
 
19+
### Requirements and assumptions
20+
21+
1. Provide types which will hold explicit pinmaps for peripherals(`PWM`, `AnalogIn`, `AnalogOut`, `SPI`, `I2C`, `UART`, `QSPI`, `CAN`).
22+
2. Provide `xxx_init_direct(xxx_t *obj, explicit_pinmap_t *)` functions to HAL API (these functions will not use pinmap tables).
23+
3. Provide additional constructors in drivers layer which will use the `xxx_init_direct(xxx_t *obj, explicit_pinmap_t*)` HAL functions.
24+
4. Provide default weak implementations of `xxx_init_direct(explicit_pinmap_t *)` functions. These functions will call standard `xxx_init(xxx_t *obj, PinName, ...)` function (backward compatibility for targets which do not support explicit pinmap mechanism).
25+
5. Provide `constexpr` utility functions to lookup for pin mapping in compile time (requires C++14).
26+
6. Provide `constexpr` pin-map tables in the header file.
27+
7. Provide macros for the pin-map tables.
28+
8. Provide `EXPLICIT_PINMAP_READY` macro in `PinNames.h`.
29+
30+
### Implementing explicit pin-map extension
31+
32+
Most of the above points are already implemented. If you want to make explicit pinmap available on your platform please perform the following steps:  
33+
34+
- Provide implementation of `xxx_init_direct(xxx_t *obj, explicit_pinmap_t *)` function (which does not use pinmap tables).
35+
  - `xxx_init()` will use pinmap tables to determine associated peripheral/function with the given pins, populate the pin-map structure and call void `xxx_init_direct()`.
36+
  - `xxx_init_direct()` will perform peripheral initialization using given explicit pinmap structure.
37+
38+
Example implementation below:
39+
40+
```
41+
void xxx_init_direct(xxx_t *obj, const PinMap *pinmap)
42+
{
43+
    obj->spi.instance = pinmap->peripheral;
44+
45+
    // pin out the xxx pins
46+
    pin_function(pinmap->pin, pinmap->function);
47+
    pin_mode(pinmap->pin, PullNone);
48+
49+
    // Some additional init code
50+
}
51+
52+
void xxx_init(xxx_t *obj, PinName pin)
53+
{
54+
    int peripheral = (int)pinmap_peripheral(pin, PinMap_xxx);
55+
    int function = (int)pinmap_find_function(pin, PinMap_xxx);
56+
57+
    const PinMap explicit_pinmap = {pin, peripheral, function};
58+
59+
    xxx_init_direct(obj, &explicit_pinmap);
60+
}
61+
```
62+
63+
- Provide `constexpr` pin-map tables in the header file.
64+
65+
Move pinmap tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new file) and add `constexpr` specifier in the pin-map table declarations.
66+
The tables are required in the header file, so can be included and used by constant expression utility functions to find and return mapping without pulling the pin-map table into the image.
67+
68+
**Note:**
69+
Please include `<mstd_cstddef>` module and use `MSTD_CONSTEXPR_OBJ_11` macro instead `constexpr` specifier. This must be done for backward compatibility with `ARM 5` compiler which does not support constant expressions. When `ARM 5` compiler is in use `MSTD_CONSTEXPR_OBJ_11` will be translated to `const`.  
70+
71+
Example pin-map table below:
72+
73+
```
74+
#include <mstd_cstddef>
75+
76+
MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_ADC[] = {
77+
    {P0_23, ADC0_SE0,    0},
78+
    {P0_10, ADC0_SE1,    0},
79+
    {P0_31, ADC0_SE3,    0},
80+
    {P1_8,  ADC0_SE4,    0},
81+
    {P2_0,  ADC0_SE5,    0},
82+
    {P2_13, ADC0_SE6,    0},
83+
    {P2_11, ADC0_SE7,    0},
84+
    {NC   , NC      ,    0}
85+
};
86+
87+
```
88+
89+
- Provide macros for pin-map tables  
90+
91+
Since pin-map table names are not common across all targets the following macros for available pin-map tables are required in `PeripheralPinMaps.h` file:
92+
93+
```
94+
#define PINMAP_ANALOGIN [PinMap ADC]
95+
#define PINMAP_ANALOGOUT [PinMap DAC]
96+
#define PINMAP_I2C_SDA [PinMap I2C SDA]
97+
#define PINMAP_I2C_SCL [PinMap I2C SCL]
98+
#define PINMAP_UART_TX [PinMap UART TX]
99+
#define PINMAP_UART_RX [PinMap UART RX]
100+
#define PINMAP_UART_CTS [PinMap UART CTS]
101+
#define PINMAP_UART_RTS [PinMap UART RTS]
102+
#define PINMAP_SPI_SCLK [PinMap SPI SCLK]
103+
#define PINMAP_SPI_MOSI [PinMap SPI MOSI]
104+
#define PINMAP_SPI_MISO [PinMap SPI MISO]
105+
#define PINMAP_SPI_SSEL [PinMap SPI SSEL]
106+
#define PINMAP_PWM [PinMap PWM]
107+
#define PINMAP_QSPI_DATA0 [PinMap QSPI DATA0]
108+
#define PINMAP_QSPI_DATA1 [PinMap QSPI DATA1]
109+
#define PINMAP_QSPI_DATA2 [PinMap QSPI DATA2]
110+
#define PINMAP_QSPI_DATA3 [PinMap QSPI DATA3]
111+
#define PINMAP_QSPI_SCLK [PinMap QSPI SCLK]
112+
#define PINMAP_QSPI_SSEL [PinMap QSPI SSEL]
113+
#define PINMAP_CAN_RD [PinMap CAN RD]
114+
#define PINMAP_CAN_TD [PinMap CAN RD]
115+
```
116+
117+
- Provide `EXPLICIT_PINMAP_READY` macro in `PinNames.h`  
118+
119+
Adding this macro will enable the explicit pin-map support for the target.
120+
121+
```
122+
/* If this macro is defined, then constexpr utility functions for pin-map seach can be used. */
123+
#define EXPLICIT_PINMAP_READY 1
124+
```
125+
126+
### Example usage/testing
127+
128+
Use code below to check if explicit pinmap extension works.
129+
130+
```
131+
int main()
132+
{
133+
    /* Regular use */
134+
    SPI spi(D1, D2, D3, D4);
135+
136+
    /* Explicit pinmap */
137+
    const spi_pinmap_t explicit_spi_pinmap = {SPI_1, D1, 2, D2, 2, D3, 2, D4, 2};
138+
    SPI spi(explicit_spi_pinmap);
139+
140+
    /* Explicit pinmap with constexpr utility function */
141+
    constexpr spi_pinmap_t explicit_spi_pinmap = get_spi_pinmap(D1, D2, D3, D4);
142+
    SPI spi(explicit_spi_pinmap);
143+
144+
    return 0;
145+
}
146+
```
147+
148+
When explicit pinmap extension is used we should get some ROM savings:  
149+
150+
```
151+
| Module                          |        .text |   .data |       .bss |
152+
|---------------------------------|--------------|---------|------------|
153+
| [lib]\c_w.l                     |    11175(+0) |  16(+0) |    348(+0) |
154+
| [lib]\fz_wm.l                   |       34(+0) |   0(+0) |      0(+0) |
155+
| [lib]\m_wm.l                    |       48(+0) |   0(+0) |      0(+0) |
156+
| anon$$obj.o                     |       32(+0) |   0(+0) | 197888(+0) |
157+
| drivers\source                  |      192(+0) |   0(+0) |      0(+0) |
158+
| features\netsocket              |      143(+0) |   0(+0) |      0(+0) |
159+
| hal\mbed_critical_section_api.o |      154(+0) |   0(+0) |      2(+0) |
160+
| hal\mbed_gpio.o                 |       96(+0) |   0(+0) |      0(+0) |
161+
| hal\mbed_pinmap_common.o        |      0(-272) |   0(+0) |      0(+0) |  // removed pinmap lib (this is common for all peripherals)
162+
| hal\mbed_ticker_api.o           |      978(+0) |   0(+0) |      0(+0) |
163+
| hal\mbed_us_ticker_api.o        |      114(+0) |   4(+0) |     65(+0) |
164+
| main.o                          |      70(+32) |   0(+0) |      0(+0) |  // extra space for explicit pinmap structure in application
165+
| platform\source                 |    5683(+46) |  64(+0) |    249(+0) |  // extra space for UART explicit pinmap structure to initialize the console
166+
| rtos\source                     |     8990(+0) | 168(+0) |   6626(+0) |
167+
| targets\TARGET_Freescale        |  16581(-816) |  12(+0) |    340(+0) |  // removed pinmaps + driver code reduction
168+
| Subtotals                       | 44290(-1010) | 264(+0) | 205518(+0) |
169+
Total Static RAM memory (data + bss): 205782(+0) bytes
170+
Total Flash memory (text + data): 44554(-1010) bytes
171+
```
172+
173+
Run FPGA tests to check if your implementation is valid:
174+
175+
```
176+
 mbed test -t ARM -m K64F -n tests-mbed_hal_fpga_ci_test_shield*
177+
```
178+
179+
**Note:**
180+
Your target must be ready to run FPGA-Test-Shield tests.
181+
Currently the following peripherals can be tested: `Analogin`, `SPI`, `I2C`, `PWM`, `UART`.

0 commit comments

Comments
 (0)