From 5b543f019f30e125720ca753221552b8820c5f4a Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Tue, 15 Oct 2019 14:54:35 +0200 Subject: [PATCH 1/4] Add porting guide for explicit pinmap extension --- docs/porting/target/explicit_pinmap.md | 181 +++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 docs/porting/target/explicit_pinmap.md diff --git a/docs/porting/target/explicit_pinmap.md b/docs/porting/target/explicit_pinmap.md new file mode 100644 index 0000000000..3bd1b83830 --- /dev/null +++ b/docs/porting/target/explicit_pinmap.md @@ -0,0 +1,181 @@ +

Explicit Pinmap extension

+ +The **Explicit Pinmap extension** allows the peripheral configuration (pin/periheral/function) to be explicitly specified in the HAL API function. + +### Overview and background + +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. + +Supported peripherals: + - `PWM` + - `AnalogIn` + - `AnalogOut` + - `SPI` + - `I2C` + - `UART` + - `QSPI` + - `CAN` +  +### Requirements and assumptions + +1. Provide types which will hold explicit pinmaps for peripherals(`PWM`, `AnalogIn`, `AnalogOut`, `SPI`, `I2C`, `UART`, `QSPI`, `CAN`). +2. Provide `xxx_init_direct(xxx_t *obj, explicit_pinmap_t *)` functions to HAL API (these functions will not use pinmap tables). +3. Provide additional constructors in drivers layer which will use the `xxx_init_direct(xxx_t *obj, explicit_pinmap_t*)` HAL functions. +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). +5. Provide `constexpr` utility functions to lookup for pin mapping in compile time (requires C++14). +6. Provide `constexpr` pin-map tables in the header file. +7. Provide macros for the pin-map tables. +8. Provide `EXPLICIT_PINMAP_READY` macro in `PinNames.h`. + +### Implementing explicit pin-map extension + +Most of the above points are already implemented. If you want to make explicit pinmap available on your platform please perform the following steps:   + +- Provide implementation of `xxx_init_direct(xxx_t *obj, explicit_pinmap_t *)` function (which does not use pinmap tables). +  - `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()`. +  - `xxx_init_direct()` will perform peripheral initialization using given explicit pinmap structure. + +Example implementation below: + +``` +void xxx_init_direct(xxx_t *obj, const PinMap *pinmap) +{ +    obj->spi.instance = pinmap->peripheral; + +    // pin out the xxx pins +    pin_function(pinmap->pin, pinmap->function); +    pin_mode(pinmap->pin, PullNone); + +    // Some additional init code +} + +void xxx_init(xxx_t *obj, PinName pin) +{ +    int peripheral = (int)pinmap_peripheral(pin, PinMap_xxx); +    int function = (int)pinmap_find_function(pin, PinMap_xxx); + +    const PinMap explicit_pinmap = {pin, peripheral, function}; + +    xxx_init_direct(obj, &explicit_pinmap); +} +``` + +- Provide `constexpr` pin-map tables in the header file. + +Move pinmap tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new file) and add `constexpr` specifier in the pin-map table declarations. +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. + +**Note:** +Please include `` 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`.   + +Example pin-map table below: + +``` +#include + +MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_ADC[] = { +    {P0_23, ADC0_SE0,    0}, +    {P0_10, ADC0_SE1,    0}, +    {P0_31, ADC0_SE3,    0}, +    {P1_8,  ADC0_SE4,    0}, +    {P2_0,  ADC0_SE5,    0}, +    {P2_13, ADC0_SE6,    0}, +    {P2_11, ADC0_SE7,    0}, +    {NC   , NC      ,    0} +}; + +``` + +- Provide macros for pin-map tables   + +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: + +``` +#define PINMAP_ANALOGIN [PinMap ADC] +#define PINMAP_ANALOGOUT [PinMap DAC] +#define PINMAP_I2C_SDA [PinMap I2C SDA] +#define PINMAP_I2C_SCL [PinMap I2C SCL] +#define PINMAP_UART_TX [PinMap UART TX] +#define PINMAP_UART_RX [PinMap UART RX] +#define PINMAP_UART_CTS [PinMap UART CTS] +#define PINMAP_UART_RTS [PinMap UART RTS] +#define PINMAP_SPI_SCLK [PinMap SPI SCLK] +#define PINMAP_SPI_MOSI [PinMap SPI MOSI] +#define PINMAP_SPI_MISO [PinMap SPI MISO] +#define PINMAP_SPI_SSEL [PinMap SPI SSEL] +#define PINMAP_PWM [PinMap PWM] +#define PINMAP_QSPI_DATA0 [PinMap QSPI DATA0] +#define PINMAP_QSPI_DATA1 [PinMap QSPI DATA1] +#define PINMAP_QSPI_DATA2 [PinMap QSPI DATA2] +#define PINMAP_QSPI_DATA3 [PinMap QSPI DATA3] +#define PINMAP_QSPI_SCLK [PinMap QSPI SCLK] +#define PINMAP_QSPI_SSEL [PinMap QSPI SSEL] +#define PINMAP_CAN_RD [PinMap CAN RD] +#define PINMAP_CAN_TD [PinMap CAN RD] +``` + +- Provide `EXPLICIT_PINMAP_READY` macro in `PinNames.h`   + +Adding this macro will enable the explicit pin-map support for the target. + +``` +/* If this macro is defined, then constexpr utility functions for pin-map seach can be used. */ +#define EXPLICIT_PINMAP_READY 1 +``` + +### Example usage/testing + +Use code below to check if explicit pinmap extension works. + +``` +int main() +{ +    /* Regular use */ +    SPI spi(D1, D2, D3, D4); + +    /* Explicit pinmap */ +    const spi_pinmap_t explicit_spi_pinmap = {SPI_1, D1, 2, D2, 2, D3, 2, D4, 2}; +    SPI spi(explicit_spi_pinmap); + +    /* Explicit pinmap with constexpr utility function */ +    constexpr spi_pinmap_t explicit_spi_pinmap = get_spi_pinmap(D1, D2, D3, D4); +    SPI spi(explicit_spi_pinmap); + +    return 0; +} +``` + +When explicit pinmap extension is used we should get some ROM savings:   + +``` +| Module                          |        .text |   .data |       .bss | +|---------------------------------|--------------|---------|------------| +| [lib]\c_w.l                     |    11175(+0) |  16(+0) |    348(+0) | +| [lib]\fz_wm.l                   |       34(+0) |   0(+0) |      0(+0) | +| [lib]\m_wm.l                    |       48(+0) |   0(+0) |      0(+0) | +| anon$$obj.o                     |       32(+0) |   0(+0) | 197888(+0) | +| drivers\source                  |      192(+0) |   0(+0) |      0(+0) | +| features\netsocket              |      143(+0) |   0(+0) |      0(+0) | +| hal\mbed_critical_section_api.o |      154(+0) |   0(+0) |      2(+0) | +| hal\mbed_gpio.o                 |       96(+0) |   0(+0) |      0(+0) | +| hal\mbed_pinmap_common.o        |      0(-272) |   0(+0) |      0(+0) |  // removed pinmap lib (this is common for all peripherals) +| hal\mbed_ticker_api.o           |      978(+0) |   0(+0) |      0(+0) | +| hal\mbed_us_ticker_api.o        |      114(+0) |   4(+0) |     65(+0) | +| main.o                          |      70(+32) |   0(+0) |      0(+0) |  // extra space for explicit pinmap structure in application +| platform\source                 |    5683(+46) |  64(+0) |    249(+0) |  // extra space for UART explicit pinmap structure to initialize the console +| rtos\source                     |     8990(+0) | 168(+0) |   6626(+0) | +| targets\TARGET_Freescale        |  16581(-816) |  12(+0) |    340(+0) |  // removed pinmaps + driver code reduction +| Subtotals                       | 44290(-1010) | 264(+0) | 205518(+0) | +Total Static RAM memory (data + bss): 205782(+0) bytes +Total Flash memory (text + data): 44554(-1010) bytes +``` + +Run FPGA tests to check if your implementation is valid: + +``` + mbed test -t ARM -m K64F -n tests-mbed_hal_fpga_ci_test_shield* +``` + +**Note:** +Your target must be ready to run FPGA-Test-Shield tests. +Currently the following peripherals can be tested: `Analogin`, `SPI`, `I2C`, `PWM`, `UART`. From 359178bf2651a3fd06e4b6e67dde2080ad26186c Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Wed, 6 Nov 2019 15:20:35 +0100 Subject: [PATCH 2/4] fix naming: explicit to static and update Overview and background section --- .../{explicit_pinmap.md => static_pinmap.md} | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) rename docs/porting/target/{explicit_pinmap.md => static_pinmap.md} (63%) diff --git a/docs/porting/target/explicit_pinmap.md b/docs/porting/target/static_pinmap.md similarity index 63% rename from docs/porting/target/explicit_pinmap.md rename to docs/porting/target/static_pinmap.md index 3bd1b83830..a0348bd6b8 100644 --- a/docs/porting/target/explicit_pinmap.md +++ b/docs/porting/target/static_pinmap.md @@ -1,39 +1,41 @@ -

Explicit Pinmap extension

+

Static Pinmap extension

-The **Explicit Pinmap extension** allows the peripheral configuration (pin/periheral/function) to be explicitly specified in the HAL API function. +The **Static Pinmap extension** allows the peripheral configuration (pin/periheral/function) to be staticly specified in the HAL API function. ### Overview and background -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. - -Supported peripherals: - - `PWM` - - `AnalogIn` - - `AnalogOut` - - `SPI` - - `I2C` - - `UART` - - `QSPI` - - `CAN` +In modern MCUs peripherals often can be mapped to different pins and each pin can have multiple functions. Mbed supports dynamic pin mapping, meaning that pins can be reconfigured at run time to be used by different driver. That provides great flexibility, but it's not free. There's non trivial ROM cost to maintain the pinmap tables and infrastructure to parse it. In some use cases this flexibility is worth the cost. Quite often pin configuration is frozen at hw design stage and doesn't require runtime modification. Shifting this configuration to compile time will allow us free memory associated with the dynamic approach. + +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. Static pinmap extension provides additional HAL API/constructors which takes pinmap as a parameter where pin/peripheral/function is specified staticly and there is no need to use the pinmap tables. + +Supported peripherals: + - `PWM` + - `AnalogIn` + - `AnalogOut` + - `SPI` + - `I2C` + - `UART` + - `QSPI` + - `CAN`   ### Requirements and assumptions -1. Provide types which will hold explicit pinmaps for peripherals(`PWM`, `AnalogIn`, `AnalogOut`, `SPI`, `I2C`, `UART`, `QSPI`, `CAN`). -2. Provide `xxx_init_direct(xxx_t *obj, explicit_pinmap_t *)` functions to HAL API (these functions will not use pinmap tables). -3. Provide additional constructors in drivers layer which will use the `xxx_init_direct(xxx_t *obj, explicit_pinmap_t*)` HAL functions. -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). +1. Provide types which will hold static pinmaps for peripherals(`PWM`, `AnalogIn`, `AnalogOut`, `SPI`, `I2C`, `UART`, `QSPI`, `CAN`). +2. Provide `xxx_init_direct(xxx_t *obj, static_pinmap_t *)` functions to HAL API (these functions will not use pinmap tables). +3. Provide additional constructors in drivers layer which will use the `xxx_init_direct(xxx_t *obj, static_pinmap_t*)` HAL functions. +4. Provide default weak implementations of `xxx_init_direct(static_pinmap_t *)` functions. These functions will call standard `xxx_init(xxx_t *obj, PinName, ...)` function (backward compatibility for targets which do not support static pinmap mechanism). 5. Provide `constexpr` utility functions to lookup for pin mapping in compile time (requires C++14). 6. Provide `constexpr` pin-map tables in the header file. 7. Provide macros for the pin-map tables. -8. Provide `EXPLICIT_PINMAP_READY` macro in `PinNames.h`. +8. Provide `STATIC_PINMAP_READY` macro in `PinNames.h`. -### Implementing explicit pin-map extension +### Implementing static pin-map extension -Most of the above points are already implemented. If you want to make explicit pinmap available on your platform please perform the following steps:   +Most of the above points are already implemented. If you want to make static pinmap available on your platform please perform the following steps:   -- Provide implementation of `xxx_init_direct(xxx_t *obj, explicit_pinmap_t *)` function (which does not use pinmap tables). -  - `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()`. -  - `xxx_init_direct()` will perform peripheral initialization using given explicit pinmap structure. +- Provide implementation of `xxx_init_direct(xxx_t *obj, static_pinmap_t *)` function (which does not use pinmap tables). +  - `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()`. +  - `xxx_init_direct()` will perform peripheral initialization using given static pinmap structure. Example implementation below: @@ -54,18 +56,18 @@ void xxx_init(xxx_t *obj, PinName pin)     int peripheral = (int)pinmap_peripheral(pin, PinMap_xxx);     int function = (int)pinmap_find_function(pin, PinMap_xxx); -    const PinMap explicit_pinmap = {pin, peripheral, function}; +    const PinMap static_pinmap = {pin, peripheral, function}; -    xxx_init_direct(obj, &explicit_pinmap); +    xxx_init_direct(obj, &static_pinmap); } ``` - Provide `constexpr` pin-map tables in the header file. -Move pinmap tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new file) and add `constexpr` specifier in the pin-map table declarations. -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. +Move pinmap tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new file) and add `constexpr` specifier in the pin-map table declarations. +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. -**Note:** +**Note:** Please include `` 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`.   Example pin-map table below: @@ -114,18 +116,18 @@ Since pin-map table names are not common across all targets the following macros #define PINMAP_CAN_TD [PinMap CAN RD] ``` -- Provide `EXPLICIT_PINMAP_READY` macro in `PinNames.h`   +- Provide `STATIC_PINMAP_READY` macro in `PinNames.h`   -Adding this macro will enable the explicit pin-map support for the target. +Adding this macro will enable the static pin-map support for the target. ``` /* If this macro is defined, then constexpr utility functions for pin-map seach can be used. */ -#define EXPLICIT_PINMAP_READY 1 +#define STATIC_PINMAP_READY 1 ``` ### Example usage/testing -Use code below to check if explicit pinmap extension works. +Use code below to check if static pinmap extension works. ``` int main() @@ -133,19 +135,19 @@ int main()     /* Regular use */     SPI spi(D1, D2, D3, D4); -    /* Explicit pinmap */ -    const spi_pinmap_t explicit_spi_pinmap = {SPI_1, D1, 2, D2, 2, D3, 2, D4, 2}; -    SPI spi(explicit_spi_pinmap); +    /* Static pinmap */ +    const spi_pinmap_t static_spi_pinmap = {SPI_1, D1, 2, D2, 2, D3, 2, D4, 2}; +    SPI spi(static_spi_pinmap); -    /* Explicit pinmap with constexpr utility function */ -    constexpr spi_pinmap_t explicit_spi_pinmap = get_spi_pinmap(D1, D2, D3, D4); -    SPI spi(explicit_spi_pinmap); +    /* Static pinmap with constexpr utility function */ +    constexpr spi_pinmap_t static_spi_pinmap = get_spi_pinmap(D1, D2, D3, D4); +    SPI spi(static_spi_pinmap);     return 0; } ``` -When explicit pinmap extension is used we should get some ROM savings:   +When static pinmap extension is used we should get some ROM savings:   ``` | Module                          |        .text |   .data |       .bss | @@ -161,8 +163,8 @@ When explicit pinmap extension is used we should get some ROM savings:   | hal\mbed_pinmap_common.o        |      0(-272) |   0(+0) |      0(+0) |  // removed pinmap lib (this is common for all peripherals) | hal\mbed_ticker_api.o           |      978(+0) |   0(+0) |      0(+0) | | hal\mbed_us_ticker_api.o        |      114(+0) |   4(+0) |     65(+0) | -| main.o                          |      70(+32) |   0(+0) |      0(+0) |  // extra space for explicit pinmap structure in application -| platform\source                 |    5683(+46) |  64(+0) |    249(+0) |  // extra space for UART explicit pinmap structure to initialize the console +| main.o                          |      70(+32) |   0(+0) |      0(+0) |  // extra space for static pinmap structure in application +| platform\source                 |    5683(+46) |  64(+0) |    249(+0) |  // extra space for UART static pinmap structure to initialize the console | rtos\source                     |     8990(+0) | 168(+0) |   6626(+0) | | targets\TARGET_Freescale        |  16581(-816) |  12(+0) |    340(+0) |  // removed pinmaps + driver code reduction | Subtotals                       | 44290(-1010) | 264(+0) | 205518(+0) | @@ -176,6 +178,6 @@ Run FPGA tests to check if your implementation is valid:  mbed test -t ARM -m K64F -n tests-mbed_hal_fpga_ci_test_shield* ``` -**Note:** -Your target must be ready to run FPGA-Test-Shield tests. +**Note:** +Your target must be ready to run FPGA-Test-Shield tests. Currently the following peripherals can be tested: `Analogin`, `SPI`, `I2C`, `PWM`, `UART`. From ca62a4e452b54749719a27577370c14ae6691bee Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Mon, 18 Nov 2019 09:37:55 +0100 Subject: [PATCH 3/4] Address the review comments. --- docs/porting/target/static_pinmap.md | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/docs/porting/target/static_pinmap.md b/docs/porting/target/static_pinmap.md index a0348bd6b8..60e763b07e 100644 --- a/docs/porting/target/static_pinmap.md +++ b/docs/porting/target/static_pinmap.md @@ -18,24 +18,13 @@ Supported peripherals:  - `QSPI`  - `CAN`   -### Requirements and assumptions - -1. Provide types which will hold static pinmaps for peripherals(`PWM`, `AnalogIn`, `AnalogOut`, `SPI`, `I2C`, `UART`, `QSPI`, `CAN`). -2. Provide `xxx_init_direct(xxx_t *obj, static_pinmap_t *)` functions to HAL API (these functions will not use pinmap tables). -3. Provide additional constructors in drivers layer which will use the `xxx_init_direct(xxx_t *obj, static_pinmap_t*)` HAL functions. -4. Provide default weak implementations of `xxx_init_direct(static_pinmap_t *)` functions. These functions will call standard `xxx_init(xxx_t *obj, PinName, ...)` function (backward compatibility for targets which do not support static pinmap mechanism). -5. Provide `constexpr` utility functions to lookup for pin mapping in compile time (requires C++14). -6. Provide `constexpr` pin-map tables in the header file. -7. Provide macros for the pin-map tables. -8. Provide `STATIC_PINMAP_READY` macro in `PinNames.h`. - ### Implementing static pin-map extension -Most of the above points are already implemented. If you want to make static pinmap available on your platform please perform the following steps:   +If you want to make static pinmap available on your platform please perform the following steps:   -- Provide implementation of `xxx_init_direct(xxx_t *obj, static_pinmap_t *)` function (which does not use pinmap tables). -  - `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()`. -  - `xxx_init_direct()` will perform peripheral initialization using given static pinmap structure. +- Provide implementation of `xxx_init_direct(xxx_t *obj, static_pinmap_t *)` function and update implementation of `xxx_init()`. +  - `xxx_init()` usees pinmap tables to determine associated peripheral/function with the given pins, populates the pin-map structure and calls void `xxx_init_direct()`. +  - `xxx_init_direct()` performs peripheral initialization using given static pinmap structure. Example implementation below: @@ -68,7 +57,7 @@ Move pinmap tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new 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. **Note:** -Please include `` 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`.   +Please include `` module and use `MSTD_CONSTEXPR_OBJ_11` macro instead `constexpr` specifier. When `PeripheralPinMaps.h` is included from the Mbed OS C++ code, we need to see it as `constexpr`, but if the target code includes it from C, it has to have it as `const`. Example pin-map table below: @@ -180,4 +169,3 @@ Run FPGA tests to check if your implementation is valid: **Note:** Your target must be ready to run FPGA-Test-Shield tests. -Currently the following peripherals can be tested: `Analogin`, `SPI`, `I2C`, `PWM`, `UART`. From 108effec25c4106f5d45552d36ff5f1680186ca4 Mon Sep 17 00:00:00 2001 From: Przemyslaw Stekiel Date: Tue, 19 Nov 2019 10:15:10 +0100 Subject: [PATCH 4/4] Resore initial edits provided by Amanda to static_pinmap.md Make initial edits, mostly for active voice, formatting and spelling. --- docs/porting/target/static_pinmap.md | 222 ++++++++++++++------------- 1 file changed, 113 insertions(+), 109 deletions(-) diff --git a/docs/porting/target/static_pinmap.md b/docs/porting/target/static_pinmap.md index 60e763b07e..9a1301ebe0 100644 --- a/docs/porting/target/static_pinmap.md +++ b/docs/porting/target/static_pinmap.md @@ -1,122 +1,121 @@ -

Static Pinmap extension

+

Static Pinmap extension

-The **Static Pinmap extension** allows the peripheral configuration (pin/periheral/function) to be staticly specified in the HAL API function. +The **Static Pinmap extension** allows you to statically specify the peripheral configuration (pin, peripheral or function) in the HAL API function. -### Overview and background +In modern MCUs, you can often map peripherals to different pins, and each pin can have multiple functions. Mbed supports dynamic pin mapping, meaning you can reconfigure pins at run time for different drivers to use. That provides great flexibility, but it's not free. There's a nontrivial ROM cost to maintain the pin map tables and infrastructure to parse it. In some use cases, this flexibility is worth the cost. Often, pin configuration is frozen at the hardware design stage and doesn't require run time modification. Shifting this configuration to compile time allows free memory associated with the dynamic approach. -In modern MCUs peripherals often can be mapped to different pins and each pin can have multiple functions. Mbed supports dynamic pin mapping, meaning that pins can be reconfigured at run time to be used by different driver. That provides great flexibility, but it's not free. There's non trivial ROM cost to maintain the pinmap tables and infrastructure to parse it. In some use cases this flexibility is worth the cost. Quite often pin configuration is frozen at hw design stage and doesn't require runtime modification. Shifting this configuration to compile time will allow us free memory associated with the dynamic approach. - -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. Static pinmap extension provides additional HAL API/constructors which takes pinmap as a parameter where pin/peripheral/function is specified staticly and there is no need to use the pinmap tables. +HAL APIs using pins take these pins in their constructor and use those pins to look up which peripheral or function to use. The process of looking up the peripheral or function requires there to be a pin map table that maps pins to peripherals or functions. This pin map table takes up ROM. Static pinmap extension provides additional HAL API constructors, which take pin map as a parameter where the pin, peripheral or function is specified statically, and there is no need to use the pin map tables. Supported peripherals: - - `PWM` - - `AnalogIn` - - `AnalogOut` - - `SPI` - - `I2C` - - `UART` - - `QSPI` - - `CAN` + + - `PWM`. + - `AnalogIn`. + - `AnalogOut`. + - `SPI`. + - `I2C`. + - `UART`. + - `QSPI`. + - `CAN`.   -### Implementing static pin-map extension +## Implementing static pin map extension -If you want to make static pinmap available on your platform please perform the following steps:   +If you want to make static pin map available on your platform please perform the following steps:   - Provide implementation of `xxx_init_direct(xxx_t *obj, static_pinmap_t *)` function and update implementation of `xxx_init()`. -  - `xxx_init()` usees pinmap tables to determine associated peripheral/function with the given pins, populates the pin-map structure and calls void `xxx_init_direct()`. -  - `xxx_init_direct()` performs peripheral initialization using given static pinmap structure. + - `xxx_init()` uses pin map tables to determine the associated peripheral or function with the given pins, populates the pin map structure and calls void `xxx_init_direct()`. + - `xxx_init_direct()` performs peripheral initialization using given static pin map structure. -Example implementation below: + Example implementation: -``` -void xxx_init_direct(xxx_t *obj, const PinMap *pinmap) -{ -    obj->spi.instance = pinmap->peripheral; + ``` + void xxx_init_direct(xxx_t *obj, const PinMap *pinmap) + { + obj->spi.instance = pinmap->peripheral; -    // pin out the xxx pins -    pin_function(pinmap->pin, pinmap->function); -    pin_mode(pinmap->pin, PullNone); + // pin out the xxx pins + pin_function(pinmap->pin, pinmap->function); + pin_mode(pinmap->pin, PullNone); -    // Some additional init code -} + // Some additional init code + } -void xxx_init(xxx_t *obj, PinName pin) -{ -    int peripheral = (int)pinmap_peripheral(pin, PinMap_xxx); -    int function = (int)pinmap_find_function(pin, PinMap_xxx); + void xxx_init(xxx_t *obj, PinName pin) + { + int peripheral = (int)pinmap_peripheral(pin, PinMap_xxx); + int function = (int)pinmap_find_function(pin, PinMap_xxx); -    const PinMap static_pinmap = {pin, peripheral, function}; + const PinMap static_pinmap = {pin, peripheral, function}; -    xxx_init_direct(obj, &static_pinmap); -} -``` + xxx_init_direct(obj, &static_pinmap); + } + ``` - Provide `constexpr` pin-map tables in the header file. -Move pinmap tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new file) and add `constexpr` specifier in the pin-map table declarations. -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. + Move pin map tables from `PeripheralPins.c` to `PeripheralPinMaps.h` (create new file) and add `constexpr` specifier in the pin map table declarations. -**Note:** -Please include `` module and use `MSTD_CONSTEXPR_OBJ_11` macro instead `constexpr` specifier. When `PeripheralPinMaps.h` is included from the Mbed OS C++ code, we need to see it as `constexpr`, but if the target code includes it from C, it has to have it as `const`. + The tables are required in the header file, so constant expression utility functions can include and use them to find and return mapping without pulling the pin map table into the image. -Example pin-map table below: +**Note:** Please include the `` module, and use the `MSTD_CONSTEXPR_OBJ_11` macro instead of the `constexpr` specifier. When `PeripheralPinMaps.h` is included from the Mbed OS C++ code, we need to see it as `constexpr`, but if the target code includes it from C, it has to have it as `const`. -``` -#include - -MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_ADC[] = { -    {P0_23, ADC0_SE0,    0}, -    {P0_10, ADC0_SE1,    0}, -    {P0_31, ADC0_SE3,    0}, -    {P1_8,  ADC0_SE4,    0}, -    {P2_0,  ADC0_SE5,    0}, -    {P2_13, ADC0_SE6,    0}, -    {P2_11, ADC0_SE7,    0}, -    {NC   , NC      ,    0} -}; + Example pin map table: -``` + ``` + #include -- Provide macros for pin-map tables   + MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_ADC[] = { + {P0_23, ADC0_SE0, 0}, + {P0_10, ADC0_SE1, 0}, + {P0_31, ADC0_SE3, 0}, + {P1_8, ADC0_SE4, 0}, + {P2_0, ADC0_SE5, 0}, + {P2_13, ADC0_SE6, 0}, + {P2_11, ADC0_SE7, 0}, + {NC , NC , 0} + }; -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: + ``` -``` -#define PINMAP_ANALOGIN [PinMap ADC] -#define PINMAP_ANALOGOUT [PinMap DAC] -#define PINMAP_I2C_SDA [PinMap I2C SDA] -#define PINMAP_I2C_SCL [PinMap I2C SCL] -#define PINMAP_UART_TX [PinMap UART TX] -#define PINMAP_UART_RX [PinMap UART RX] -#define PINMAP_UART_CTS [PinMap UART CTS] -#define PINMAP_UART_RTS [PinMap UART RTS] -#define PINMAP_SPI_SCLK [PinMap SPI SCLK] -#define PINMAP_SPI_MOSI [PinMap SPI MOSI] -#define PINMAP_SPI_MISO [PinMap SPI MISO] -#define PINMAP_SPI_SSEL [PinMap SPI SSEL] -#define PINMAP_PWM [PinMap PWM] -#define PINMAP_QSPI_DATA0 [PinMap QSPI DATA0] -#define PINMAP_QSPI_DATA1 [PinMap QSPI DATA1] -#define PINMAP_QSPI_DATA2 [PinMap QSPI DATA2] -#define PINMAP_QSPI_DATA3 [PinMap QSPI DATA3] -#define PINMAP_QSPI_SCLK [PinMap QSPI SCLK] -#define PINMAP_QSPI_SSEL [PinMap QSPI SSEL] -#define PINMAP_CAN_RD [PinMap CAN RD] -#define PINMAP_CAN_TD [PinMap CAN RD] -``` +- Provide macros for pin map tables. -- Provide `STATIC_PINMAP_READY` macro in `PinNames.h`   + Because pin map table names are not common across all targets, the following macros for available pin map tables are required in the `PeripheralPinMaps.h` file: -Adding this macro will enable the static pin-map support for the target. + ``` + #define PINMAP_ANALOGIN [PinMap ADC] + #define PINMAP_ANALOGOUT [PinMap DAC] + #define PINMAP_I2C_SDA [PinMap I2C SDA] + #define PINMAP_I2C_SCL [PinMap I2C SCL] + #define PINMAP_UART_TX [PinMap UART TX] + #define PINMAP_UART_RX [PinMap UART RX] + #define PINMAP_UART_CTS [PinMap UART CTS] + #define PINMAP_UART_RTS [PinMap UART RTS] + #define PINMAP_SPI_SCLK [PinMap SPI SCLK] + #define PINMAP_SPI_MOSI [PinMap SPI MOSI] + #define PINMAP_SPI_MISO [PinMap SPI MISO] + #define PINMAP_SPI_SSEL [PinMap SPI SSEL] + #define PINMAP_PWM [PinMap PWM] + #define PINMAP_QSPI_DATA0 [PinMap QSPI DATA0] + #define PINMAP_QSPI_DATA1 [PinMap QSPI DATA1] + #define PINMAP_QSPI_DATA2 [PinMap QSPI DATA2] + #define PINMAP_QSPI_DATA3 [PinMap QSPI DATA3] + #define PINMAP_QSPI_SCLK [PinMap QSPI SCLK] + #define PINMAP_QSPI_SSEL [PinMap QSPI SSEL] + #define PINMAP_CAN_RD [PinMap CAN RD] + #define PINMAP_CAN_TD [PinMap CAN RD] + ``` -``` -/* If this macro is defined, then constexpr utility functions for pin-map seach can be used. */ -#define STATIC_PINMAP_READY 1 -``` +- Provide `STATIC_PINMAP_READY` macro in `PinNames.h`   + + Adding this macro enables the static pin map support for the target. + + ``` + /* If this macro is defined, you can use constexpr utility functions for pin map search. */ + #define STATIC_PINMAP_READY 1 + ``` -### Example usage/testing +## Testing -Use code below to check if static pinmap extension works. +Use the code below to test the static pin map extension: ``` int main() @@ -136,36 +135,41 @@ int main() } ``` -When static pinmap extension is used we should get some ROM savings:   +When you use the static pin map extension, you save on ROM:   ``` -| Module                          |        .text |   .data |       .bss | +| Module | .text | .data | .bss | |---------------------------------|--------------|---------|------------| -| [lib]\c_w.l                     |    11175(+0) |  16(+0) |    348(+0) | -| [lib]\fz_wm.l                   |       34(+0) |   0(+0) |      0(+0) | -| [lib]\m_wm.l                    |       48(+0) |   0(+0) |      0(+0) | -| anon$$obj.o                     |       32(+0) |   0(+0) | 197888(+0) | -| drivers\source                  |      192(+0) |   0(+0) |      0(+0) | -| features\netsocket              |      143(+0) |   0(+0) |      0(+0) | -| hal\mbed_critical_section_api.o |      154(+0) |   0(+0) |      2(+0) | -| hal\mbed_gpio.o                 |       96(+0) |   0(+0) |      0(+0) | -| hal\mbed_pinmap_common.o        |      0(-272) |   0(+0) |      0(+0) |  // removed pinmap lib (this is common for all peripherals) -| hal\mbed_ticker_api.o           |      978(+0) |   0(+0) |      0(+0) | -| hal\mbed_us_ticker_api.o        |      114(+0) |   4(+0) |     65(+0) | -| main.o                          |      70(+32) |   0(+0) |      0(+0) |  // extra space for static pinmap structure in application -| platform\source                 |    5683(+46) |  64(+0) |    249(+0) |  // extra space for UART static pinmap structure to initialize the console -| rtos\source                     |     8990(+0) | 168(+0) |   6626(+0) | -| targets\TARGET_Freescale        |  16581(-816) |  12(+0) |    340(+0) |  // removed pinmaps + driver code reduction -| Subtotals                       | 44290(-1010) | 264(+0) | 205518(+0) | +| [lib]\c_w.l | 11175(+0) | 16(+0) | 348(+0) | +| [lib]\fz_wm.l | 34(+0) | 0(+0) | 0(+0) | +| [lib]\m_wm.l | 48(+0) | 0(+0) | 0(+0) | +| anon$$obj.o | 32(+0) | 0(+0) | 197888(+0) | +| drivers\source | 192(+0) | 0(+0) | 0(+0) | +| features\netsocket | 143(+0) | 0(+0) | 0(+0) | +| hal\mbed_critical_section_api.o | 154(+0) | 0(+0) | 2(+0) | +| hal\mbed_gpio.o | 96(+0) | 0(+0) | 0(+0) | +| hal\mbed_pinmap_common.o | 0(-272) | 0(+0) | 0(+0) | // removed pinmap lib (this is common for all peripherals) +| hal\mbed_pinmap_common.o | 0(-272) | 0(+0) | 0(+0) | // remove pinmap lib (this is common for all peripherals) +| hal\mbed_ticker_api.o | 978(+0) | 0(+0) | 0(+0) | +| hal\mbed_us_ticker_api.o | 114(+0) | 4(+0) | 65(+0) | +| main.o | 70(+32) | 0(+0) | 0(+0) | // extra space for static pinmap structure in application +| platform\source | 5683(+46) | 64(+0) | 249(+0) | // extra space for UART static pinmap structure to initialize the console +| main.o | 70(+32) | 0(+0) | 0(+0) | // extra space for static pin map structure in application +| platform\source | 5683(+46) | 64(+0) | 249(+0) | // extra space for UART static pin map structure to initialize the console +| rtos\source | 8990(+0) | 168(+0) | 6626(+0) | +| targets\TARGET_Freescale | 16581(-816) | 12(+0) | 340(+0) | // removed pinmaps + driver code reduction +| targets\TARGET_Freescale | 16581(-816) | 12(+0) | 340(+0) | // remove pin maps and driver code reduction +| Subtotals | 44290(-1010) | 264(+0) | 205518(+0) | Total Static RAM memory (data + bss): 205782(+0) bytes Total Flash memory (text + data): 44554(-1010) bytes +Total static RAM memory (data + bss): 205782(+0) bytes +Total flash memory (text + data): 44554(-1010) bytes ``` -Run FPGA tests to check if your implementation is valid: +Run FPGA tests to check whether your implementation is valid: ```  mbed test -t ARM -m K64F -n tests-mbed_hal_fpga_ci_test_shield* ``` -**Note:** -Your target must be ready to run FPGA-Test-Shield tests. +**Note:** Your target must be ready to run FPGA-Test-Shield tests.