From 8dcdaf9236485812472b2d0898b0490cb8d01638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Thu, 22 Feb 2018 23:33:11 +0100 Subject: [PATCH] provisions for representing pins via resources in settings --- framework/resources.c | 17 ++++++++-------- framework/rsc_enum.h | 2 +- platform/hw_utils.c | 47 +++++++++++++++++++++++++++++++++++++++++++ platform/hw_utils.h | 27 +++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/framework/resources.c b/framework/resources.c index 7ab418e..0968585 100644 --- a/framework/resources.c +++ b/framework/resources.c @@ -21,10 +21,8 @@ const char *const rsc_names[] = { #undef X }; -// Check that EXTI have higher values than GPIOs in the enum -// (determines the logic in the name generation code below) -COMPILER_ASSERT(R_EXTI0 > R_PA0); - +COMPILER_ASSERT(R_PF15 < R_EXTI0); +COMPILER_ASSERT(R_PA0 == 0); const char * rsc_get_name(Resource rsc) { @@ -34,21 +32,22 @@ const char * rsc_get_name(Resource rsc) // we assume the returned value is not stored anywhere // and is directly used in a sprintf call, hence a static buffer is OK to use - if (rsc >= R_EXTI0) { + if (rsc >= R_EXTI0 && rsc <= R_EXTI15) { uint8_t index = rsc - R_EXTI0; SNPRINTF(gpionamebuf, 8, "EXTI%d", index); return gpionamebuf; } - if (rsc >= R_PA0) { + // R_PA0 is 0 + if (rsc <= R_PF15) { // we assume the returned value is not stored anywhere // and is directly used in a sprintf call. - uint8_t index = rsc - R_PA0; + uint8_t index = rsc; SNPRINTF(gpionamebuf, 8, "P%c%d", 'A'+(index/16), index%16); return gpionamebuf; } - return rsc_names[rsc]; + return rsc_names[rsc - R_EXTI15 - 1]; } @@ -222,7 +221,7 @@ void rsc_print_all_available(IniWriter *iw) uint32_t count0 = (iw->count + iw->skip); bool first = true; - for (uint32_t rsc = 0; rsc < R_PA0; rsc++) { + for (uint32_t rsc = R_EXTI15+1; rsc < R_NONE; rsc++) { if (RSC_IS_HELD(scratchmap, (Resource)rsc)) continue; if (!first) iw_string(iw, ", "); diff --git a/framework/rsc_enum.h b/framework/rsc_enum.h index 3d4f3cf..4dae01b 100644 --- a/framework/rsc_enum.h +++ b/framework/rsc_enum.h @@ -59,9 +59,9 @@ typedef enum hw_resource Resource; /** Enum of all resources */ enum hw_resource { #define X(res_name) R_##res_name, - XX_RESOURCES XX_RESOURCES_GPIO XX_RESOURCES_EXTI + XX_RESOURCES #undef X R_NONE, RESOURCE_COUNT = R_NONE, diff --git a/platform/hw_utils.c b/platform/hw_utils.c index 8c9c3f5..3753ef8 100644 --- a/platform/hw_utils.c +++ b/platform/hw_utils.c @@ -395,6 +395,53 @@ bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, } +/** Parse a string representation of a pin directly to a resource constant */ +Resource parse_pin2rsc(const char *str, bool *suc) +{ + char pname; + uint8_t pnum; + + if (!parse_pin(str, &pname, &pnum)) { + *suc = false; + return R_NONE; + } + + return hw_pin2resource(pname, pnum, suc); +} + +/** Convert a resource to a pin name - uses a static buffer, result must not be stored! */ +char *str_rsc2pin(Resource rsc) +{ + static char buf[4]; + uint32_t index = rsc - R_PA0; + uint32_t portnum = (index/16); + uint8_t pinnum = (uint8_t) (index % 16); + if (portnum >= PORTS_COUNT) return ""; + buf[0] = (char) ('A' + portnum); + if (pinnum>9) { + buf[1] = '1'; + buf[2] = (char) ('0' + (pinnum - 10)); + buf[3] = 0; + } else { + buf[1] = (char) ('0' + pinnum); + buf[2] = 0; + } + return buf; +} + +/** Convert a pin resource to it's LL lib values */ +bool pinRsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin) +{ + uint32_t index = rsc - R_PA0; + uint32_t pname = (index/16); + uint8_t pnum = (uint8_t) (index % 16); + if (pname >= PORTS_COUNT) return false; + *port = GPIO_PERIPHS[pname]; + *llpin = LL_GPIO_PINS[pnum]; + return true; +} + + void hw_periph_clock_enable(void *periph) { // GPIOs are enabled by default on start-up diff --git a/platform/hw_utils.h b/platform/hw_utils.h index 8fec5d6..c5f4c89 100644 --- a/platform/hw_utils.h +++ b/platform/hw_utils.h @@ -50,6 +50,33 @@ GPIO_TypeDef *hw_port2periph(char port_name, bool *suc); */ bool parse_pin(const char *str, char *targetName, uint8_t *targetNumber); +/** + * Parse a string representation of a pin directly to a resource constant + * + * @param[in] str - source string - e.g. PA0 or A0 + * @param[out] suc - written to false on failure + * @return the parsed resource + */ +Resource parse_pin2rsc(const char *str, bool *suc); + +/** + * Convert a pin resource to it's LL lib values + * + * @param[in] rsc - resource to process + * @param[out] port - output port + * @param[out] llpin - output LL pin mask + * @return success + */ +bool pinRsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin); + +/** + * Convert a resource to a pin name - uses a static buffer, result must not be stored! + * + * @param[in] rsc - resource to print + * @return a pointer to a static buffer used for exporting the names + */ +char *str_rsc2pin(Resource rsc); + /** * Parse a port name (one character) - validates that it's within range *