• uP port mapping

    From john larkin@3:770/3 to All on Tuesday, September 10, 2024 12:12:46
    XPost: sci.electronics.design

    Something I've wondered about:

    Suppose we have a c program running on some little uP, and it has some
    integer variable value, 8 or 12 bits or something, and wants to drive
    a parallel DAC off-chip.

    The msb...lsb bits of the variable obviously have to get to the right
    pins of the DAC.

    So, in general, how does one pick the physical i/o port pins on the
    uP, to get the order right? The PCB layout is easiest if we just wire
    the DAC to the handiest port pins.

    One could test and bit-bang each bit and port individually, and then
    strobe the DAC, but that's inelegant.

    In the RP2040 chip, one can apparently write to a register in a
    PIO/state machine block, where each bit of the register can be
    assigned to drive a physical port pin. I think there are some
    constraints on the selected pins.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From The Natural Philosopher@3:770/3 to john larkin on Thursday, September 12, 2024 16:29:13
    XPost: sci.electronics.design

    On 10/09/2024 20:12, john larkin wrote:
    Something I've wondered about:

    Suppose we have a c program running on some little uP, and it has some integer variable value, 8 or 12 bits or something, and wants to drive
    a parallel DAC off-chip.

    The msb...lsb bits of the variable obviously have to get to the right
    pins of the DAC.

    So, in general, how does one pick the physical i/o port pins on the
    uP, to get the order right? The PCB layout is easiest if we just wire
    the DAC to the handiest port pins.

    TBH once you go to at least 2 layer and dont worry about super small
    size, that isn't very hard. You can use traces with via's as jumpers.
    Once the board is done there is no added cost


    Helped by the fact that the PIO pins on the boards go in order IIRC.


    One could test and bit-bang each bit and port individually, and then
    strobe the DAC, but that's inelegant.

    Wastes CPU too.

    In the RP2040 chip, one can apparently write to a register in a
    PIO/state machine block, where each bit of the register can be
    assigned to drive a physical port pin. I think there are some
    constraints on the selected pins.

    I think so, though I have not found the need to use it.
    Obviously for deeply parallel operations that works. But modern
    practice is to implement some sort of high speed serial bus.
    In general that is fast enough for a DAC anyway


    --
    For in reason, all government without the consent of the governed is the
    very definition of slavery.

    Jonathan Swift

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Theo@3:770/3 to john larkin on Thursday, September 12, 2024 17:43:04
    XPost: sci.electronics.design

    In comp.sys.raspberry-pi john larkin <jl@650pot.com> wrote:
    Something I've wondered about:

    Suppose we have a c program running on some little uP, and it has some integer variable value, 8 or 12 bits or something, and wants to drive
    a parallel DAC off-chip.

    The msb...lsb bits of the variable obviously have to get to the right
    pins of the DAC.

    So, in general, how does one pick the physical i/o port pins on the
    uP, to get the order right? The PCB layout is easiest if we just wire
    the DAC to the handiest port pins.

    A lot of MPUs have 'ports', ie you don't have individual GPIOs, but P0.0 to P0.7, P1.0-P1.7, etc. You can write to a whole 8 bit port in a single operation. That way you know to wire up P0.0 to the LSB of your DAC and
    P0.7 to the MSB, or maybe use P1.0-1.3 for the upper 4 bits.

    Slightly surprisingly I don't see that on the RP2040 datasheet, it looks
    like you can only set single bits at a time. It seems you have to use the
    PIOs to get parallel transfers. Maybe you can also do something with DMA?

    There's a 'PIO and DMA (a logic analyser)" in 3.2.3 of the C/C++ SDK doc: https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf

    which says:

    "Pin Groups (Mapping)
    We mentioned earlier that there are four pin groups to configure, to connect a state machine’s internal
    data buses to the GPIOs it manipulates. A state machine accesses all pins within a group at once, and
    pin groups can overlap. So far we have seen the out, side-set and in pin groups. The fourth is set.
    The out group is the pins affected by shifting out data from the OSR, using out pins or out pindirs, up to
    32 bits at a time. The set group is used with set pins and set pindirs instructions, up to 5 bits at a time,
    with data that is encoded directly in the instruction. It’s useful for toggling control signals. The side-set
    group is similar to the set group, but runs simultaneously with another instruction. Note: mov pin uses
    the in or out group, depending on direction."

    and 3.2.5 in the RP2040 datasheet says:

    "3.2.5. Pin Mapping
    PIO controls the output level and direction of up to 32 GPIOs, and can observe their input levels. On every system clock
    cycle, each state machine may do none, one, or both of the following:
    • Change the level or direction of some GPIOs via an OUT or SET instruction, or read some GPIOs via an IN instruction
    • Change the level or direction of some GPIOs via a side-set operation
    Each of these operations is on one of four contiguous ranges of GPIOs, with the base and count of each range
    configured via each state machine’s PINCTRL register. There is a range for each of OUT, SET, IN and side-set operations.
    Each range can cover any of the GPIOs accessible to a given PIO block (on RP2040 this is the 30 user GPIOs), and the
    ranges can overlap.
    For each individual GPIO output (level and direction separately), PIO considers all 8 writes that may have occurred on
    that cycle, and applies the write from the highest-numbered state machine. If the same state machine performs a SET
    /OUT and a side-set on the same GPIO simultaneously, the side-set is used. If no state machine writes to this GPIO
    output, its value does not change from the previous cycle.
    Generally each state machine’s outputs are mapped to a distinct group of GPIOs, implementing some peripheral
    interface."

    so I suppose you want all of your pins consecutively in the same pin group.

    It looks like this example does parallel output: https://github.com/raspberrypi/pico-examples/blob/master/gpio/hello_7segment/hello_7segment.c
    via gpio_set_mask() (set to high all the bits in the mask) and gpio_clr_mask() but I wouldn't say for sure that it's atomic.

    Theo

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From The Natural Philosopher@3:770/3 to Theo on Thursday, September 12, 2024 18:24:41
    XPost: sci.electronics.design

    On 12/09/2024 17:43, Theo wrote:
    In comp.sys.raspberry-pi john larkin <jl@650pot.com> wrote:
    Something I've wondered about:

    Suppose we have a c program running on some little uP, and it has some
    integer variable value, 8 or 12 bits or something, and wants to drive
    a parallel DAC off-chip.

    The msb...lsb bits of the variable obviously have to get to the right
    pins of the DAC.

    So, in general, how does one pick the physical i/o port pins on the
    uP, to get the order right? The PCB layout is easiest if we just wire
    the DAC to the handiest port pins.

    A lot of MPUs have 'ports', ie you don't have individual GPIOs, but P0.0 to P0.7, P1.0-P1.7, etc. You can write to a whole 8 bit port in a single operation. That way you know to wire up P0.0 to the LSB of your DAC and
    P0.7 to the MSB, or maybe use P1.0-1.3 for the upper 4 bits.

    Slightly surprisingly I don't see that on the RP2040 datasheet, it looks
    like you can only set single bits at a time. It seems you have to use the PIOs to get parallel transfers. Maybe you can also do something with DMA?

    There's a 'PIO and DMA (a logic analyser)" in 3.2.3 of the C/C++ SDK doc: https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf

    which says:

    "Pin Groups (Mapping)
    We mentioned earlier that there are four pin groups to configure, to connect a state machine’s internal
    data buses to the GPIOs it manipulates. A state machine accesses all pins within a group at once, and
    pin groups can overlap. So far we have seen the out, side-set and in pin groups. The fourth is set.
    The out group is the pins affected by shifting out data from the OSR, using out pins or out pindirs, up to
    32 bits at a time. The set group is used with set pins and set pindirs instructions, up to 5 bits at a time,
    with data that is encoded directly in the instruction. It’s useful for toggling control signals. The side-set
    group is similar to the set group, but runs simultaneously with another instruction. Note: mov pin uses
    the in or out group, depending on direction."

    and 3.2.5 in the RP2040 datasheet says:

    "3.2.5. Pin Mapping
    PIO controls the output level and direction of up to 32 GPIOs, and can observe their input levels. On every system clock
    cycle, each state machine may do none, one, or both of the following:
    • Change the level or direction of some GPIOs via an OUT or SET instruction, or read some GPIOs via an IN instruction
    • Change the level or direction of some GPIOs via a side-set operation
    Each of these operations is on one of four contiguous ranges of GPIOs, with the base and count of each range
    configured via each state machine’s PINCTRL register. There is a range for each of OUT, SET, IN and side-set operations.
    Each range can cover any of the GPIOs accessible to a given PIO block (on RP2040 this is the 30 user GPIOs), and the
    ranges can overlap.
    For each individual GPIO output (level and direction separately), PIO considers all 8 writes that may have occurred on
    that cycle, and applies the write from the highest-numbered state machine. If the same state machine performs a SET
    /OUT and a side-set on the same GPIO simultaneously, the side-set is used. If no state machine writes to this GPIO
    output, its value does not change from the previous cycle.
    Generally each state machine’s outputs are mapped to a distinct group of GPIOs, implementing some peripheral
    interface."

    so I suppose you want all of your pins consecutively in the same pin group.

    It looks like this example does parallel output: https://github.com/raspberrypi/pico-examples/blob/master/gpio/hello_7segment/hello_7segment.c
    via gpio_set_mask() (set to high all the bits in the mask) and gpio_clr_mask()
    but I wouldn't say for sure that it's atomic.

    Theo

    I read something that indicates that groups of pins have their own tiny processor! You dont talk to the pins, you talk to the processor instead.

    --
    Climate Change: Socialism wearing a lab coat.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From john larkin@3:770/3 to tnp@invalid.invalid on Thursday, September 12, 2024 12:35:15
    XPost: sci.electronics.design

    On Thu, 12 Sep 2024 18:24:41 +0100, The Natural Philosopher <tnp@invalid.invalid> wrote:

    On 12/09/2024 17:43, Theo wrote:
    In comp.sys.raspberry-pi john larkin <jl@650pot.com> wrote:
    Something I've wondered about:

    Suppose we have a c program running on some little uP, and it has some
    integer variable value, 8 or 12 bits or something, and wants to drive
    a parallel DAC off-chip.

    The msb...lsb bits of the variable obviously have to get to the right
    pins of the DAC.

    So, in general, how does one pick the physical i/o port pins on the
    uP, to get the order right? The PCB layout is easiest if we just wire
    the DAC to the handiest port pins.

    A lot of MPUs have 'ports', ie you don't have individual GPIOs, but P0.0 to >> P0.7, P1.0-P1.7, etc. You can write to a whole 8 bit port in a single
    operation. That way you know to wire up P0.0 to the LSB of your DAC and
    P0.7 to the MSB, or maybe use P1.0-1.3 for the upper 4 bits.

    Slightly surprisingly I don't see that on the RP2040 datasheet, it looks
    like you can only set single bits at a time. It seems you have to use the >> PIOs to get parallel transfers. Maybe you can also do something with DMA? >>
    There's a 'PIO and DMA (a logic analyser)" in 3.2.3 of the C/C++ SDK doc:
    https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf

    which says:

    "Pin Groups (Mapping)
    We mentioned earlier that there are four pin groups to configure, to connect a state machine’s internal
    data buses to the GPIOs it manipulates. A state machine accesses all pins within a group at once, and
    pin groups can overlap. So far we have seen the out, side-set and in pin groups. The fourth is set.
    The out group is the pins affected by shifting out data from the OSR, using out pins or out pindirs, up to
    32 bits at a time. The set group is used with set pins and set pindirs instructions, up to 5 bits at a time,
    with data that is encoded directly in the instruction. It’s useful for toggling control signals. The side-set
    group is similar to the set group, but runs simultaneously with another instruction. Note: mov pin uses
    the in or out group, depending on direction."

    and 3.2.5 in the RP2040 datasheet says:

    "3.2.5. Pin Mapping
    PIO controls the output level and direction of up to 32 GPIOs, and can observe their input levels. On every system clock
    cycle, each state machine may do none, one, or both of the following:
    • Change the level or direction of some GPIOs via an OUT or SET instruction, or read some GPIOs via an IN instruction
    • Change the level or direction of some GPIOs via a side-set operation
    Each of these operations is on one of four contiguous ranges of GPIOs, with the base and count of each range
    configured via each state machine’s PINCTRL register. There is a range for each of OUT, SET, IN and side-set operations.
    Each range can cover any of the GPIOs accessible to a given PIO block (on RP2040 this is the 30 user GPIOs), and the
    ranges can overlap.
    For each individual GPIO output (level and direction separately), PIO considers all 8 writes that may have occurred on
    that cycle, and applies the write from the highest-numbered state machine. If the same state machine performs a SET
    /OUT and a side-set on the same GPIO simultaneously, the side-set is used. If no state machine writes to this GPIO
    output, its value does not change from the previous cycle.
    Generally each state machine’s outputs are mapped to a distinct group of GPIOs, implementing some peripheral
    interface."

    so I suppose you want all of your pins consecutively in the same pin group. >>
    It looks like this example does parallel output:
    https://github.com/raspberrypi/pico-examples/blob/master/gpio/hello_7segment/hello_7segment.c
    via gpio_set_mask() (set to high all the bits in the mask) and gpio_clr_mask()
    but I wouldn't say for sure that it's atomic.

    Theo

    I read something that indicates that groups of pins have their own tiny >processor! You dont talk to the pins, you talk to the processor instead.


    RP2040 has I think 2 PIO blocks and each has a couple of hardware
    programmable state machines, and those can be set up to drive pins.
    I'm mostly concerned now with a PCB schematic design, picking the
    appropriate and easy-to-route pins from the CPU to things.

    My general question, for various processors, is how to associate bits
    in integer variables with physical pins on the chip.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Theo@3:770/3 to john larkin on Thursday, September 12, 2024 22:28:42
    XPost: sci.electronics.design

    In comp.sys.raspberry-pi john larkin <jl@650pot.com> wrote:
    RP2040 has I think 2 PIO blocks and each has a couple of hardware programmable state machines, and those can be set up to drive pins.
    I'm mostly concerned now with a PCB schematic design, picking the
    appropriate and easy-to-route pins from the CPU to things.

    My general question, for various processors, is how to associate bits
    in integer variables with physical pins on the chip.

    This is the function of a 'pinmux'. Different chips have different capabilities of the pinmux, but it's rare to be able to connect any GPIO to
    any pin - that's more FPGA territory. Typically the pinmux is just about selecting one of multiple fixed functions for a given pin (SPI1_MISO/I2C3_SDA/UART2_TX/...)

    So either you route your DAC to consecutive pins (D0 to GPIOn, D1 to n+1,
    ..., ideally where n is a multiple of 8), or you're prepared to do the necessary bit shuffling in software (which can be slow and non-atomic). I'd suggest sticking to consecutive ordering if you can.

    (although I have no experience of the RP2xxx GPIO/PIO shenanigans)

    Theo

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From The Natural Philosopher@3:770/3 to Theo on Friday, September 13, 2024 09:36:31
    XPost: sci.electronics.design

    On 12/09/2024 22:28, Theo wrote:
    In comp.sys.raspberry-pi john larkin <jl@650pot.com> wrote:
    RP2040 has I think 2 PIO blocks and each has a couple of hardware
    programmable state machines, and those can be set up to drive pins.
    I'm mostly concerned now with a PCB schematic design, picking the
    appropriate and easy-to-route pins from the CPU to things.

    My general question, for various processors, is how to associate bits
    in integer variables with physical pins on the chip.

    This is the function of a 'pinmux'. Different chips have different capabilities of the pinmux, but it's rare to be able to connect any GPIO to any pin - that's more FPGA territory. Typically the pinmux is just about selecting one of multiple fixed functions for a given pin (SPI1_MISO/I2C3_SDA/UART2_TX/...)

    That is my understanding, too. What the pins do is programmable, but
    not tire mappings to specific registers inside the processor

    So either you route your DAC to consecutive pins (D0 to GPIOn, D1 to n+1, ..., ideally where n is a multiple of 8), or you're prepared to do the necessary bit shuffling in software (which can be slow and non-atomic). I'd suggest sticking to consecutive ordering if you can.

    Yes.

    (although I have no experience of the RP2xxx GPIO/PIO shenanigans)

    I have - a very very little - but I have spent some time reading the
    docs to see at least if the Pi PICO is suitable for various speculative projects or not.

    There is a massive amount of shit it *can* do that probably only one
    person in a hundred would ever use.

    It just so happens that driving parallel connected external logic is
    something I have an interest in, so I read that bit... :-)

    Theo

    --
    Civilization exists by geological consent, subject to change without notice.
    – Will Durant

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From The Natural Philosopher@3:770/3 to john larkin on Friday, September 13, 2024 09:30:22
    XPost: sci.electronics.design

    On 12/09/2024 20:35, john larkin wrote:
    RP2040 has I think 2 PIO blocks and each has a couple of hardware programmable state machines, and those can be set up to drive pins.
    I'm mostly concerned now with a PCB schematic design, picking the
    appropriate and easy-to-route pins from the CPU to things.

    It would be unusual for the pins in numerical order not to be part of
    the same PIO block
    So you might as well design the PCB that way.

    My general question, for various processors, is how to associate bits
    in integer variables with physical pins on the chip.

    Well that is a software issue.
    I thought that on the Pi PICO there was software to do a bulk set of pins

    Yes.

    https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#functions70 There is a set pins by mask - mask is up to 32 bits - and clear pins by
    mask.

    So presumably if you invert the mask (XOR with FFFF) and clear with that
    and set with the original mask and add a strobe pulse as well to latch
    the data, its three calls in C....or have I misunderstood..not sure if
    you can set AND clear simultaneously.

    Now irrespective of whether the hardware supports more, that's as good
    as you are going to get with the C SDK, and presumably only assembler is faster. And presumably the actual gpio functions are written in
    assembler anyway. So that (c gpio) will be as good as it gets.

    What that leads to in respect of your original question is to treat the
    gpio numbers as if they represented the bits in order.

    https://forums.raspberrypi.com/viewtopic.php?t=326719

    That conversation implies that they are.

    So gpio 0-12 should e.g. go to the DAC lsb->msb set of bots.

    These are all arranged in order down one side of the board, so it should
    be easy

    Good luck!

    --
    No Apple devices were knowingly used in the preparation of this post.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)