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.
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.
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
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.
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
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.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 371 |
Nodes: | 16 (2 / 14) |
Uptime: | 36:59:53 |
Calls: | 7,932 |
Calls today: | 2 |
Files: | 12,998 |
Messages: | 5,805,537 |