mirror of https://github.com/ARMmbed/mbed-os.git
Add pinmap utility functions
Add 2 new pinmap utility functions: -pinmap_find_peripheral_pins -pinmap_list_has_pin Also add the new type PinList which contains a list of pins allowing for NC and duplicate entries.pull/9449/head
parent
8669417e7b
commit
0dee05a843
|
@ -104,3 +104,77 @@ uint32_t pinmap_function(PinName pin, const PinMap *map)
|
|||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
bool pinmap_find_peripheral_pins(const PinList *whitelist, const PinList *blacklist, int per, const PinMap *const *maps, PinName **pins, uint32_t count)
|
||||
{
|
||||
/*
|
||||
* This function uses recursion to find a suitable set of pins which meet the requirements.
|
||||
* Recursion is at max the number of pinmaps passed in - the 'count' parameter. Because of this
|
||||
* there is no risk of a stack overflow due to unbounded recursion.
|
||||
*
|
||||
* Below is a psuedo code example of this function's operation when finding a set of 4 pins.
|
||||
* The recursion depth is indicated by the number in front.
|
||||
*
|
||||
* 1. Given 4 maps and a peripheral find 4 suitable pins
|
||||
* 2. Given 4 maps, a peripheral and 1 pin find 3 suitable pins
|
||||
* 3. Given 4 maps, a peripheral and 2 pins find 2 suitable pins
|
||||
* 4. Given 4 maps, a peripheral and 3 pins find 1 suitable pin
|
||||
* 4. Return success if all pins are found, return failure if there are no suitable pins, otherwise choose the next pin and retry
|
||||
* 3. Return success if all pins are found, return failure if there are no suitable pins, otherwise choose the next pin and retry
|
||||
* 2. Return success if all pins are found, return failure if there are no suitable pins, otherwise choose the next pin and retry
|
||||
* 1. Return success if all pins are found, return failure if there are no suitable pins, otherwise choose the next pin and retry
|
||||
*
|
||||
*/
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
const PinMap *map = maps[i];
|
||||
PinName *pin = pins[i];
|
||||
if (*pin == NC) {
|
||||
for (; map->pin != NC; map++) {
|
||||
if (map->peripheral != per) {
|
||||
continue;
|
||||
}
|
||||
if (!pinmap_list_has_pin(whitelist, map->pin)) {
|
||||
// Not part of this form factor
|
||||
continue;
|
||||
}
|
||||
if (pinmap_list_has_pin(blacklist, map->pin)) {
|
||||
// Restricted pin
|
||||
continue;
|
||||
}
|
||||
bool already_in_use = false;
|
||||
for (uint32_t j = 0; j < count; j++) {
|
||||
if (j == i) {
|
||||
// Don't compare with self
|
||||
continue;
|
||||
}
|
||||
if (map->pin == *pins[j]) {
|
||||
already_in_use = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (already_in_use) {
|
||||
continue;
|
||||
}
|
||||
*pin = map->pin;
|
||||
if (pinmap_find_peripheral_pins(whitelist, blacklist, per, maps, pins, count)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*pin = NC;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pinmap_list_has_pin(const PinList *list, PinName pin)
|
||||
{
|
||||
for (uint32_t i = 0; i < list->count; i++) {
|
||||
if (list->pins[i] == pin) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
81
hal/pinmap.h
81
hal/pinmap.h
|
@ -21,6 +21,7 @@
|
|||
#define MBED_PINMAP_H
|
||||
|
||||
#include "PinNames.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -32,6 +33,11 @@ typedef struct {
|
|||
int function;
|
||||
} PinMap;
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
const PinName *pins;
|
||||
} PinList;
|
||||
|
||||
void pin_function(PinName pin, int function);
|
||||
void pin_mode(PinName pin, PinMode mode);
|
||||
|
||||
|
@ -42,6 +48,81 @@ void pinmap_pinout(PinName pin, const PinMap *map);
|
|||
uint32_t pinmap_find_peripheral(PinName pin, const PinMap *map);
|
||||
uint32_t pinmap_find_function(PinName pin, const PinMap *map);
|
||||
|
||||
/**
|
||||
* Find a combination of pins suitable for use given the constraints
|
||||
*
|
||||
* This function finds pins which meet these specific properties:
|
||||
* - The pin is part of the form factor
|
||||
* - The pin is not in the restricted list
|
||||
* - The pin is contained within the respective pinmap
|
||||
* - The pin belongs to the given peripheral
|
||||
* - Each pin found is distinct; in the example below
|
||||
* mosi and miso will never be assigned the same pin
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* #include "mbed.h"
|
||||
* #include "pinmap.h"
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* int per = spi_master_cs_pinmap()->peripheral;
|
||||
* const PinList *pins_ff = pinmap_ff_default_pins();
|
||||
* const PinList *pins_avoid = pinmap_restricted_pins();
|
||||
* PinName mosi = NC;
|
||||
* PinName miso = NC;
|
||||
* PinName sclk = NC;
|
||||
* PinName ssel = NC;
|
||||
* const PinMap *maps[] = {
|
||||
* spi_master_mosi_pinmap(),
|
||||
* spi_master_miso_pinmap(),
|
||||
* spi_master_clk_pinmap(),
|
||||
* spi_master_cs_pinmap()
|
||||
* };
|
||||
* PinName *pins[] = {
|
||||
* &mosi,
|
||||
* &miso,
|
||||
* &sclk,
|
||||
* &ssel
|
||||
* };
|
||||
* if (pinmap_find_peripheral_pins(pins_ff, pins_avoid, per, maps, pins, sizeof(maps) / sizeof(maps[0]))) {
|
||||
* printf("Found SPI pins to test instance %i with:\n"
|
||||
* " mosi=%s\n"
|
||||
* " miso=%s\n"
|
||||
* " sclk=%s\n"
|
||||
* " ssel=%s\n", per,
|
||||
* pinmap_ff_default_pin_to_string(mosi),
|
||||
* pinmap_ff_default_pin_to_string(miso),
|
||||
* pinmap_ff_default_pin_to_string(sclk),
|
||||
* pinmap_ff_default_pin_to_string(ssel));
|
||||
* } else {
|
||||
* printf("Could not find SPI combination to test %i\n", per);
|
||||
* }
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param whitelist List of pins to choose from
|
||||
* @param blacklist List of pins which cannot be used
|
||||
* @param per Peripheral to which the pins belong
|
||||
* @param maps An array of pin maps to select from
|
||||
* @param pins An array of pins to find. Pins already set to a value will be
|
||||
* left unchanged. Only pins initialized to NC will be updated by this function
|
||||
* @param count The size of maps and pins
|
||||
* @return true if a suitable combination of pins was found and
|
||||
* written to the pins array, otherwise false
|
||||
*/
|
||||
bool pinmap_find_peripheral_pins(const PinList *whitelist, const PinList *blacklist, int per, const PinMap *const *maps, PinName **pins, uint32_t count);
|
||||
|
||||
/**
|
||||
* Check if the pin is in the list
|
||||
*
|
||||
* @param list pin list to check
|
||||
* @param pin pin to check for in the list
|
||||
* @return true if the pin is in the list, false otherwise
|
||||
*/
|
||||
bool pinmap_list_has_pin(const PinList *list, PinName pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue