diff --git a/framework/resources.c b/framework/resources.c index 6898028..bcd985d 100644 --- a/framework/resources.c +++ b/framework/resources.c @@ -136,6 +136,15 @@ error_t rsc_claim_gpios(Unit *unit, char port_name, uint16_t pins) return E_SUCCESS; } +error_t rsc_claim_pin(Unit *unit, char port_name, uint8_t pin) +{ + bool suc = true; + Resource rsc = pin2resource(port_name, pin, &suc); + if (!suc) return E_BAD_CONFIG; + TRY(rsc_claim(unit, rsc)); + return E_SUCCESS; +} + /** * Free a resource for other use * diff --git a/framework/resources.h b/framework/resources.h index 8290cf4..cd39c3c 100644 --- a/framework/resources.h +++ b/framework/resources.h @@ -13,6 +13,7 @@ void rsc_init_registry(void); +error_t rsc_claim_pin(Unit *unit, char port_name, uint8_t pin); error_t rsc_claim(Unit *unit, Resource rsc); error_t rsc_claim_range(Unit *unit, Resource rsc0, Resource rsc1); /** diff --git a/platform/pin_utils.c b/platform/pin_utils.c index a9a5af0..58a623c 100644 --- a/platform/pin_utils.c +++ b/platform/pin_utils.c @@ -271,3 +271,43 @@ void deinit_unit_pins(Unit *unit) } } } + + +error_t configure_gpio_alternate(char port_name, uint8_t pin_num, uint32_t af) +{ + bool suc = true; + GPIO_TypeDef *port = port2periph(port_name, &suc); + uint32_t ll_pin = pin2ll(pin_num, &suc); + if (!suc) return E_BAD_CONFIG; + + if (pin_num < 8) + LL_GPIO_SetAFPin_0_7(port, ll_pin, af); + else + LL_GPIO_SetAFPin_8_15(port, ll_pin, af); + + LL_GPIO_SetPinMode(port, ll_pin, LL_GPIO_MODE_ALTERNATE); + + return E_SUCCESS; +} + +error_t configure_sparse_pins(char port_name, uint16_t mask, GPIO_TypeDef **port_dest, uint32_t mode, uint32_t otype) +{ + bool suc = true; + GPIO_TypeDef *port = port2periph(port_name, &suc); + if (!suc) return E_BAD_CONFIG; + + for (int i = 0; i < 16; i++) { + if (mask & (1<anf = pp_bool(pp); priv->dnf = pp_u8(pp); priv->speed = pp_u8(pp); + + if (version >= 1) { + priv->remap = pp_u8(pp); + } } /** Write to a binary buffer for storing in Flash */ @@ -47,12 +51,13 @@ static void UI2C_writeBinary(Unit *unit, PayloadBuilder *pb) { struct priv *priv = unit->data; - pb_u8(pb, 0); // version + pb_u8(pb, 1); // version pb_u8(pb, priv->periph_num); pb_bool(pb, priv->anf); pb_u8(pb, priv->dnf); pb_u8(pb, priv->speed); + pb_u8(pb, priv->remap); } // ------------------------------------------------------------------------ @@ -229,32 +234,11 @@ static error_t UI2C_init(Unit *unit) #endif // first, we have to claim the pins - Resource r_sda = pin2resource(portname, pin_sda, &suc); - Resource r_scl = pin2resource(portname, pin_scl, &suc); - if (!suc) return E_BAD_CONFIG; - - TRY(rsc_claim(unit, r_sda)); - TRY(rsc_claim(unit, r_scl)); - - priv->port = port2periph(portname, &suc); - priv->ll_pin_scl = pin2ll(pin_scl, &suc); - priv->ll_pin_sda = pin2ll(pin_sda, &suc); - if (!suc) return E_BAD_CONFIG; - - // configure AF - if (pin_scl < 8) LL_GPIO_SetAFPin_0_7(priv->port, priv->ll_pin_scl, af_i2c); - else LL_GPIO_SetAFPin_8_15(priv->port, priv->ll_pin_scl, af_i2c); - - if (pin_sda < 8) LL_GPIO_SetAFPin_0_7(priv->port, priv->ll_pin_sda, af_i2c); - else LL_GPIO_SetAFPin_8_15(priv->port, priv->ll_pin_sda, af_i2c); - - LL_GPIO_SetPinMode(priv->port, priv->ll_pin_scl, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinMode(priv->port, priv->ll_pin_sda, LL_GPIO_MODE_ALTERNATE); - - // set as OpenDrain (this may not be needed - TODO check) - LL_GPIO_SetPinOutputType(priv->port, priv->ll_pin_scl, LL_GPIO_OUTPUT_OPENDRAIN); - LL_GPIO_SetPinOutputType(priv->port, priv->ll_pin_sda, LL_GPIO_OUTPUT_OPENDRAIN); + TRY(rsc_claim_pin(unit, portname, pin_sda)); + TRY(rsc_claim_pin(unit, portname, pin_scl)); + configure_gpio_alternate(portname, pin_sda, af_i2c); + configure_gpio_alternate(portname, pin_scl, af_i2c); if (priv->periph_num == 1) { __HAL_RCC_I2C1_CLK_ENABLE(); @@ -265,8 +249,7 @@ static error_t UI2C_init(Unit *unit) /* Disable the selected I2Cx Peripheral */ LL_I2C_Disable(priv->periph); LL_I2C_ConfigFilters(priv->periph, - priv->anf ? LL_I2C_ANALOGFILTER_ENABLE - : LL_I2C_ANALOGFILTER_DISABLE, + (priv->anf ? LL_I2C_ANALOGFILTER_ENABLE : LL_I2C_ANALOGFILTER_DISABLE), priv->dnf); LL_I2C_SetTiming(priv->periph, timing); diff --git a/units/spi/unit_spi.c b/units/spi/unit_spi.c index a315d50..d0b4b02 100644 --- a/units/spi/unit_spi.c +++ b/units/spi/unit_spi.c @@ -25,12 +25,7 @@ struct priv { uint16_t ssn_pins; //!< SSN pin mask SPI_TypeDef *periph; - GPIO_TypeDef *ssn_port; - GPIO_TypeDef *spi_port; - uint32_t ll_pin_miso; - uint32_t ll_pin_mosi; - uint32_t ll_pin_sck; }; // ------------------------------------------------------------------------ @@ -291,34 +286,13 @@ static error_t USPI_init(Unit *unit) #endif // first, we have to claim the pins - Resource r_mosi = pin2resource(spi_portname, pin_mosi, &suc); - Resource r_miso = pin2resource(spi_portname, pin_miso, &suc); - Resource r_sck = pin2resource(spi_portname, pin_sck, &suc); - if (!suc) return E_BAD_CONFIG; - - TRY(rsc_claim(unit, r_mosi)); - TRY(rsc_claim(unit, r_miso)); - TRY(rsc_claim(unit, r_sck)); - - priv->spi_port = port2periph(spi_portname, &suc); - priv->ll_pin_mosi = pin2ll(pin_mosi, &suc); - priv->ll_pin_miso = pin2ll(pin_miso, &suc); - priv->ll_pin_sck = pin2ll(pin_sck, &suc); - if (!suc) return E_BAD_CONFIG; - - // configure AF - if (pin_mosi < 8) LL_GPIO_SetAFPin_0_7(priv->spi_port, priv->ll_pin_mosi, af_spi); - else LL_GPIO_SetAFPin_8_15(priv->spi_port, priv->ll_pin_mosi, af_spi); + TRY(rsc_claim_pin(unit, spi_portname, pin_mosi)); + TRY(rsc_claim_pin(unit, spi_portname, pin_miso)); + TRY(rsc_claim_pin(unit, spi_portname, pin_sck)); - if (pin_miso < 8) LL_GPIO_SetAFPin_0_7(priv->spi_port, priv->ll_pin_miso, af_spi); - else LL_GPIO_SetAFPin_8_15(priv->spi_port, priv->ll_pin_miso, af_spi); - - if (pin_sck < 8) LL_GPIO_SetAFPin_0_7(priv->spi_port, priv->ll_pin_sck, af_spi); - else LL_GPIO_SetAFPin_8_15(priv->spi_port, priv->ll_pin_sck, af_spi); - - LL_GPIO_SetPinMode(priv->spi_port, priv->ll_pin_mosi, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinMode(priv->spi_port, priv->ll_pin_miso, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinMode(priv->spi_port, priv->ll_pin_sck, LL_GPIO_MODE_ALTERNATE); + configure_gpio_alternate(spi_portname, pin_mosi, af_spi); + configure_gpio_alternate(spi_portname, pin_miso, af_spi); + configure_gpio_alternate(spi_portname, pin_sck, af_spi); if (priv->periph_num == 1) { __HAL_RCC_SPI1_CLK_ENABLE(); @@ -328,22 +302,10 @@ static error_t USPI_init(Unit *unit) // configure SSN GPIOs { - priv->ssn_port = port2periph(priv->ssn_port_name, &suc); - if (!suc) return E_BAD_CONFIG; - // Claim all needed pins TRY(rsc_claim_gpios(unit, priv->ssn_port_name, priv->ssn_pins)); - - 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); - LL_GPIO_SetPinMode(priv->ssn_port, ll_pin, LL_GPIO_MODE_OUTPUT); - LL_GPIO_SetPinOutputType(priv->ssn_port, ll_pin, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinSpeed(priv->ssn_port, ll_pin, LL_GPIO_SPEED_FREQ_HIGH); - } - } - + TRY(configure_sparse_pins(priv->ssn_port_name, priv->ssn_pins, &priv->ssn_port, + LL_GPIO_MODE_OUTPUT, LL_GPIO_OUTPUT_PUSHPULL)); // Set the initial state - all high priv->ssn_port->ODR &= priv->ssn_pins; } @@ -359,21 +321,10 @@ static error_t USPI_init(Unit *unit) dbg("Presc is %d", (int) presc); LL_SPI_SetBaudRatePrescaler(priv->periph, presc); - LL_SPI_SetClockPolarity(priv->periph, priv->cpol ? - LL_SPI_POLARITY_HIGH : - LL_SPI_POLARITY_LOW); - - LL_SPI_SetClockPhase(priv->periph, priv->cpha ? - LL_SPI_PHASE_1EDGE : - LL_SPI_PHASE_2EDGE); - - LL_SPI_SetTransferDirection(priv->periph, priv->tx_only ? - LL_SPI_HALF_DUPLEX_TX : - LL_SPI_FULL_DUPLEX); - - LL_SPI_SetTransferBitOrder(priv->periph, priv->lsb_first ? - LL_SPI_LSB_FIRST : - LL_SPI_MSB_FIRST); + LL_SPI_SetClockPolarity(priv->periph, priv->cpol ? LL_SPI_POLARITY_HIGH : LL_SPI_POLARITY_LOW); + LL_SPI_SetClockPhase(priv->periph, priv->cpha ? LL_SPI_PHASE_1EDGE : LL_SPI_PHASE_2EDGE); + LL_SPI_SetTransferDirection(priv->periph, priv->tx_only ? LL_SPI_HALF_DUPLEX_TX : LL_SPI_FULL_DUPLEX); + LL_SPI_SetTransferBitOrder(priv->periph, priv->lsb_first ? LL_SPI_LSB_FIRST : LL_SPI_MSB_FIRST); // TODO data size?