diff --git a/framework/resources.c b/framework/resources.c index 2ff7035..6898028 100644 --- a/framework/resources.c +++ b/framework/resources.c @@ -73,19 +73,12 @@ error_t rsc_claim(Unit *unit, Resource rsc) assert_param(rsc < RESOURCE_COUNT); assert_param(unit != NULL); + dbg("%s claims %s", unit->name, rsc_get_name(rsc)); + if (RSC_IS_HELD(global_rscmap, rsc)) { // this whole branch is just reporting the error Unit *holder = ureg_get_rsc_owner(rsc); - - if (holder == NULL) { - // It must be one of the dummy built-in units - if (RSC_IS_HELD(UNIT_SYSTEM.resources, rsc)) - holder = &UNIT_SYSTEM; - else if (RSC_IS_HELD(UNIT_PLATFORM.resources, rsc)) - holder = &UNIT_SYSTEM; - } - assert_param(holder != NULL); dbg("ERROR!! Unit %s failed to claim resource %s, already held by %s!", @@ -154,6 +147,8 @@ void rsc_free(Unit *unit, Resource rsc) assert_param(rsc_initialized); assert_param(rsc < RESOURCE_COUNT); + dbg("Free resource %s", rsc_get_name(rsc)); + if (RSC_IS_FREE(global_rscmap, rsc)) return; // free it in any unit that holds it @@ -197,7 +192,8 @@ void rsc_free_range(Unit *unit, Resource rsc0, Resource rsc1) } /** - * Tear down a unit - release all resources owned by the unit + * Tear down a unit - release all resources owned by the unit. + * Also de-init all GPIOs * * @param unit - unit to tear down; free only resources claimed by this unit */ @@ -206,6 +202,8 @@ void rsc_teardown(Unit *unit) assert_param(rsc_initialized); assert_param(unit != NULL); + deinit_unit_pins(unit); + for (uint32_t i = 0; i < RSCMAP_LEN; i++) { global_rscmap[i] &= ~unit->resources[i]; unit->resources[i] = 0; diff --git a/framework/unit_registry.c b/framework/unit_registry.c index 79d7710..dda027f 100644 --- a/framework/unit_registry.c +++ b/framework/unit_registry.c @@ -355,14 +355,22 @@ static void export_unit_do(UlistEntry *li, IniWriter *iw) iw_section(iw, "%s:%s@%d", pUnit->driver->name, pUnit->name, (int)pUnit->callsign); if (pUnit->status != E_SUCCESS) { - // special message for failed unit die to resource - if (pUnit->status == E_RESOURCE_NOT_AVAILABLE) { - iw_comment(iw, "!!! %s not available, already held by %s", - rsc_get_name(pUnit->failed_rsc), - rsc_get_owner_name(pUnit->failed_rsc)); - } else { - iw_comment(iw, "!!! %s", error_get_message(pUnit->status)); + // temporarily force comments ON + bool sc = SystemSettings.ini_comments; + SystemSettings.ini_comments = true; + { + // special message for failed unit die to resource + if (pUnit->status == E_RESOURCE_NOT_AVAILABLE) { + iw_comment(iw, "!!! %s not available, already held by %s", + rsc_get_name(pUnit->failed_rsc), + rsc_get_owner_name(pUnit->failed_rsc)); + } + else { + iw_comment(iw, "!!! %s", error_get_message(pUnit->status)); + } + iw_cmt_newline(iw); } + SystemSettings.ini_comments = sc; } pUnit->driver->cfgWriteIni(pUnit, iw); } @@ -540,5 +548,9 @@ Unit *ureg_get_rsc_owner(Resource resource) } li = li->next; } + + if (RSC_IS_HELD(UNIT_SYSTEM.resources, resource)) return &UNIT_SYSTEM; + if (RSC_IS_HELD(UNIT_PLATFORM.resources, resource)) return &UNIT_PLATFORM; + return NULL; } diff --git a/platform/pin_utils.c b/platform/pin_utils.c index db1a50d..a9a5af0 100644 --- a/platform/pin_utils.c +++ b/platform/pin_utils.c @@ -260,3 +260,14 @@ uint16_t port_pack(uint16_t spread, uint16_t mask) } return result; } + +void deinit_unit_pins(Unit *unit) +{ + for (uint32_t rsc = R_PA0; rsc <= R_PF0; rsc++) { + if (RSC_IS_HELD(unit->resources, rsc)) { + GPIO_TypeDef *port = port_periphs[(rsc-R_PA0) / 16]; + uint32_t ll_pin = ll_pins[(rsc-R_PA0)%16]; + LL_GPIO_SetPinMode(port, ll_pin, LL_GPIO_MODE_ANALOG); + } + } +} diff --git a/platform/pin_utils.h b/platform/pin_utils.h index ead2b34..a996cde 100644 --- a/platform/pin_utils.h +++ b/platform/pin_utils.h @@ -68,4 +68,11 @@ uint16_t port_spread(uint16_t packed, uint16_t mask); */ uint16_t port_pack(uint16_t spread, uint16_t mask); +/** + * Set all GPIO resources held by unit to analog + * + * @param unit - holding unit + */ +void deinit_unit_pins(Unit *unit); + #endif //GEX_PIN_UTILS_H diff --git a/units/digital_in/unit_din.c b/units/digital_in/unit_din.c index 01c321b..1071e57 100644 --- a/units/digital_in/unit_din.c +++ b/units/digital_in/unit_din.c @@ -161,23 +161,7 @@ static error_t DI_init(Unit *unit) /** Tear down the unit */ static void DI_deInit(Unit *unit) { - struct priv *priv = unit->data; - - if (unit->status == E_SUCCESS) { - assert_param(priv->port); - - bool suc = true; - uint16_t mask = 1; - for (int i = 0; i < 16; i++, mask <<= 1) { - if (priv->pins & mask) { - uint32_t ll_pin = pin2ll((uint8_t) i, &suc); - assert_param(suc); // this should never fail if we got this far - - // configure the pin as analog - LL_GPIO_SetPinMode(priv->port, ll_pin, LL_GPIO_MODE_ANALOG); - } - } - } + // pins are de-inited during teardown // Release all resources rsc_teardown(unit); diff --git a/units/digital_out/unit_dout.c b/units/digital_out/unit_dout.c index cb6f48d..5c1671d 100644 --- a/units/digital_out/unit_dout.c +++ b/units/digital_out/unit_dout.c @@ -151,25 +151,7 @@ static error_t DO_init(Unit *unit) /** Tear down the unit */ static void DO_deInit(Unit *unit) { - struct priv *priv = unit->data; - - // de-init the pins only if inited correctly - if (unit->status == E_SUCCESS) { - assert_param(priv->port); - - bool suc = true; - uint16_t mask = 1; - for (int i = 0; i < 16; i++, mask <<= 1) { - if (priv->pins & mask) { - - uint32_t ll_pin = pin2ll((uint8_t) i, &suc); - assert_param(suc); // this should never fail if we got this far - - // configure the pin as analog - LL_GPIO_SetPinMode(priv->port, ll_pin, LL_GPIO_MODE_ANALOG); - } - } - } + // pins are de-inited during teardown // Release all resources rsc_teardown(unit); diff --git a/units/i2c/unit_i2c.c b/units/i2c/unit_i2c.c index 796691a..ba5060b 100644 --- a/units/i2c/unit_i2c.c +++ b/units/i2c/unit_i2c.c @@ -2,6 +2,7 @@ // Created by MightyPork on 2018/01/02. // +#include #include "comm/messages.h" #include "unit_base.h" #include "utils/avrlibc.h" @@ -12,6 +13,8 @@ /** Private data structure */ struct priv { uint8_t periph_num; //!< 1 or 2 + uint8_t remap; //!< I2C remap option + bool anf; //!< Enable analog noise filter uint8_t dnf; //!< Enable digital noise filter (1-15 ... max spike width) uint8_t speed; //!< 0 - Standard, 1 - Fast, 2 - Fast+ @@ -63,6 +66,9 @@ static error_t UI2C_loadIni(Unit *unit, const char *key, const char *value) if (streq(key, "device")) { priv->periph_num = (uint8_t) avr_atoi(value); } + else if (streq(key, "remap")) { + priv->remap = (uint8_t) avr_atoi(value); + } else if (streq(key, "analog-filter")) { priv->anf = str_parse_yn(value, &suc); } @@ -88,6 +94,22 @@ static void UI2C_writeIni(Unit *unit, IniWriter *iw) iw_comment(iw, "Peripheral number (I2Cx)"); iw_entry(iw, "device", "%d", (int)priv->periph_num); + iw_comment(iw, "Pin mappings (SCL,SDA)"); +#if GEX_PLAT_F072_DISCOVERY + iw_comment(iw, " I2C1: (0) B6,B7 (1) B8,B9"); + iw_comment(iw, " I2C2: (0) B10,B11 (1) B13,B14"); +#elif GEX_PLAT_F103_BLUEPILL + #error "NO IMPL" +#elif GEX_PLAT_F303_DISCOVERY + #error "NO IMPL" +#elif GEX_PLAT_F407_DISCOVERY + #error "NO IMPL" +#else + #error "BAD PLATFORM!" +#endif + iw_entry(iw, "remap", "%d", (int)priv->remap); + + iw_cmt_newline(iw); iw_comment(iw, "Speed: 1-Standard, 2-Fast, 3-Fast+"); iw_entry(iw, "speed", "%d", (int)priv->speed); @@ -157,17 +179,38 @@ static error_t UI2C_init(Unit *unit) #if GEX_PLAT_F072_DISCOVERY // scl - 6 or 8 for I2C1, 10 for I2C2 // sda - 7 or 9 for I2C1, 11 for I2C2 - portname = 'B'; - if (priv->periph_num == 1) { - pin_scl = 8; - pin_sda = 9; + // I2C1 + if (priv->remap == 0) { + af_i2c = LL_GPIO_AF_1; + portname = 'B'; + pin_scl = 6; + pin_sda = 7; + } else if (priv->remap == 1) { + af_i2c = LL_GPIO_AF_1; + portname = 'B'; + pin_scl = 8; + pin_sda = 9; + } else { + return E_BAD_CONFIG; + } } else { - pin_scl = 10; - pin_sda = 12; + // I2C2 + if (priv->remap == 0) { + af_i2c = LL_GPIO_AF_1; + portname = 'B'; + pin_scl = 10; + pin_sda = 11; + } else if (priv->remap == 1) { + af_i2c = LL_GPIO_AF_5; + portname = 'B'; + pin_scl = 13; + pin_sda = 14; + } else { + return E_BAD_CONFIG; + } } - af_i2c = LL_GPIO_AF_1; if (priv->speed == 1) timing = 0x00301D2B; // Standard else if (priv->speed == 2) @@ -244,7 +287,6 @@ static void UI2C_deInit(Unit *unit) // de-init the pins & peripheral only if inited correctly if (unit->status == E_SUCCESS) { assert_param(priv->periph); - assert_param(priv->port); LL_I2C_DeInit(priv->periph); @@ -253,9 +295,6 @@ static void UI2C_deInit(Unit *unit) } else { __HAL_RCC_I2C2_CLK_DISABLE(); } - - LL_GPIO_SetPinMode(priv->port, priv->ll_pin_sda, LL_GPIO_MODE_ANALOG); - LL_GPIO_SetPinMode(priv->port, priv->ll_pin_scl, LL_GPIO_MODE_ANALOG); } // Release all resources diff --git a/units/neopixel/unit_neopixel.c b/units/neopixel/unit_neopixel.c index b5b1a21..585fdf2 100644 --- a/units/neopixel/unit_neopixel.c +++ b/units/neopixel/unit_neopixel.c @@ -121,13 +121,7 @@ static error_t Npx_init(Unit *unit) /** Tear down the unit */ static void Npx_deInit(Unit *unit) { - struct priv *priv = unit->data; - - if (unit->status == E_SUCCESS) { - assert_param(priv->port); - // configure the pin as analog - LL_GPIO_SetPinMode(priv->port, priv->ll_pin, LL_GPIO_MODE_ANALOG); - } + // pins are de-inited during teardown // Release all resources rsc_teardown(unit); diff --git a/units/spi/unit_spi.c b/units/spi/unit_spi.c index 055c396..a315d50 100644 --- a/units/spi/unit_spi.c +++ b/units/spi/unit_spi.c @@ -124,7 +124,6 @@ static void USPI_writeIni(Unit *unit, IniWriter *iw) { struct priv *priv = unit->data; - iw_cmt_newline(iw); iw_comment(iw, "Peripheral number (SPIx)"); iw_entry(iw, "device", "%d", (int)priv->periph_num); @@ -228,7 +227,6 @@ static error_t USPI_init(Unit *unit) // TODO #if GEX_PLAT_F072_DISCOVERY - // SPI1 - many options // sck, miso, mosi, af @@ -394,8 +392,6 @@ static void USPI_deInit(Unit *unit) // de-init the pins & peripheral only if inited correctly if (unit->status == E_SUCCESS) { assert_param(priv->periph); - assert_param(priv->spi_port); - assert_param(priv->ssn_port); LL_SPI_DeInit(priv->periph); @@ -404,22 +400,6 @@ static void USPI_deInit(Unit *unit) } else { __HAL_RCC_SPI2_CLK_DISABLE(); } - - LL_GPIO_SetPinMode(priv->spi_port, priv->ll_pin_mosi, LL_GPIO_MODE_ANALOG); - LL_GPIO_SetPinMode(priv->spi_port, priv->ll_pin_mosi, LL_GPIO_MODE_ANALOG); - LL_GPIO_SetPinMode(priv->spi_port, priv->ll_pin_sck, LL_GPIO_MODE_ANALOG); - - // de-init all SSN pins - bool suc = true; - uint16_t mask = 1; - for (int i = 0; i < 16; i++, mask <<= 1) { - if (priv->ssn_pins & mask) { - uint32_t ll_pin = pin2ll((uint8_t) i, &suc); - assert_param(suc); - // configure the pin as analog - LL_GPIO_SetPinMode(priv->ssn_port, ll_pin, LL_GPIO_MODE_ANALOG); - } - } } // Release all resources