PinState vs PinFunction

Posted on
  • I'm trying to figure out the gpio and other pin stuff for the esp8266 and I'm confused by the PinState and PinFunction. I see the enums, so I see the difference, but why is there jshSetPinState but no jshSetPinFunction? Is that stm32 heritage and setting the PinState forces a specific corresponding PinFunction?

  • Well, it's pretty much STM32, but I think it probably applies to most other stuff too.

    PinState

    This almost directly correlates to the pin's output registers - pullup/down/open drain/etc - and whether the pin is connected to GPIO or to an actual peripheral

    The mentions of USART/etc in there are basically wrong and should really disappear (they can usually be replaced with some other PinState).

    PinFunction

    This is information about what peripherals are connected to a pin (it's stored in the pinInfo array) - for instance a pin might do SPI1_MOSI/I2C_SCL and TIM1_CH1. The pinInfo array is dragged almost directly from the STM32 datasheet - it's used to sanity check what the user's asking for, and in some cases (like PWM) to actually choose the hardware that gets used.

    The other thing it contains is the AF number - which probably is STM32-specific. There's a big multiplexer on each pin that connects it to different peripherals, and the AF number in each PinFunction is fed into that in order to make the pin do what's needed. It's actually kind of a pin state thing, but it's tied to the peripheral, so is part of PinFunction.

    So the two aren't quite the same. For instance if you're controlling WS2811 pixels, you'd usually use SPIx_MOSI (the pin function), some specific AF number, and AF_OUTPUT (pin state), but if you run them off the full 5v, the voltage swing on 3.3v isn't enough, and you'd add a pullup resistor and would then use the AF_OPENDRAIN pin state (while still using the same pin function including the AF).

  • ... and there actually is a SetPinFunction: https://github.com/espruino/Espruino/blo­b/master/targets/stm32/jshardware.c#L897­

    (it could do with a slight re-name :)

    It's just not exported from jshardware.c, because jshSPI/USART/I2CSetup (and timer/etc) are the only things that need it, as it's tied very specifically to the peripherals.

  • Question: JSHPINSTATE_IS_PULLUP(state) does not include I2C, i.e., the pull-up is not enabled for I2C even though the bus does require pull-ups. This means that external pull-ups must be provided. Is that intentional?

  • Are the internal pullups on the STM32-series even strong enough for I2C? Would enabling the pullups automatically interfere with interoperability with 5v I2C devices on 5v tolerant pins?

  • Yes, external pullups are required at the moment. The internal ones are 40k (on STM32), and most I2C things seem to want 10k at most?

    I implemented it a while back but I think I did try it initially and couldn't get it working reliably with the internal pullups alone (on STM32F1) so I just left them off. As @DrAzzy says, with pullups, I think a 5v I2C signal would pull the 3.3v rail up to 5v (although only a bit - it probably doesn't matter).

    Nothing should stop users from setting pinMode and then calling I2C.setup though, if they want to try it...

    I remember being fed up that I couldn't get OneWire to work with the internal pullups either - but I think in that case it's because STM32F1's registers meant that the output data and pullups were somehow linked together.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

PinState vs PinFunction

Posted by Avatar for tve @tve

Actions