[En-Nut-Discussion] Problem with STM32 pin configuration

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Tue Oct 6 11:46:21 CEST 2015


>>>>> "Ole" == Ole Reinhardt <ole.reinhardt at embedded-it.de> writes:

    Ole> Hi Uwe, there is a problem with your new pin configuration scheme,
    Ole> which you committed a few days ago, which breaks several drivers.

    Ole> The problem is, that the GCC preprocessor does not know anything
    Ole> about types. But in several places, a preprocessor comparison like

    Ole> #if (SPI_CS0 != PIN_NONE)

    Ole> is used, where PIN_NONE is of the enum type nutgpio_t.

    Ole> The above comparison is always true, as the preprocessor takes
    Ole> SPI_CS0 and PIN_NONE as identifiers, not as macros. These are then
    Ole> both replaced by 0. So finally the comparison is always true.

    Ole> This kind of preprocessor comparisons are at least used in

    Ole> arch/cm3/dev/stm/stm32_spi.c arch/cm3/dev/stm/stm32_emac.c

    Ole> but perhaps ins several more.

    Ole> See also https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html#SEC38
    Ole> for a detailed explanation.


    Ole> Could you please have a look at it? Unfortunately I do not have an
    Ole> idea for an elegant solution.

Thanks for the hint. Argh, I stumbled on that problem before with the vendor
headers :-(

There are only the (5) places you pointed out where a compile time test for
unused pins is done. With your solution, every of the about 200 pins needs a
corresponding #define. Also pin name would vary when used for compile time
vs. run-time usage. Let us consider if that is needed.

The test in stm32_emac.s can easily be rewritten as
    if (Stm32GpioConfigSet(EMAC_PHY_CLOCK_MCO, GPIO_CFG_PERIPHAL |
        GPIO_CFG_OUTPUT | EMAC_GPIO_SPEED, GPIO_AF_MCO) == 0) {
        /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */
        RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE)) | RCC_CFGR_MCO1_1;
    }
without defines and with very low runtime impact.

The 4 tests for unconnected pins in stm32_spi.h are harder to work around,
as long as the SPI driver uses per-device files.

In the long run, I tend to rewrite the spi-driver as one driver as
stm32_i2cbus_v2.c already is. This will also require run-time decision on
the pins used and remove the defines.

On the short run, the setup seems broken anyhow:
#if (SPI_CS0 != 0)
#warning bla
#define SPIBUS_SCK_PORT     (uint32_t)(stm32_port_nr2gpio[SPI_CS0  >> 8])
#define SPIBUS_SCK_PIN      (SPI_CS0 & 0xf)
...
This mixes SCK with CS0. Argh :-(

Again, SPIBUS_CSx_INIT(x) can be used without compile-time defines with low
run-time impact. For SPIBUS_CSx_SET and For SPIBUS_CSx_CLR I will probably
introduce "void Stm32GpioSet(nutgpio_t gpio, int value)" as exported
function. The function would return without setting anything if called with
PIN_NONE. The run-time effect on  Stm32SpiChipSelect() should be barable.

I will try to fix and test.

B.t.w. I in spibus.h, don't see a place to store private hardware data like
in i2cbus.h:
    /*! \brief Private data of the hardware specific implementation. */
    void *bus_icb;

Do I miss something? Otherwise, can we extend struct _NUTSPIBUS  for
    void *bus_icb;
at the end, without causing damage to others?

Any other Ideas?

Bye
-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------


More information about the En-Nut-Discussion mailing list