Path: ...!2.eu.feeder.erje.net!feeder.erje.net!news.szaf.org!nntp-feed.chiark.greenend.org.uk!ewrotcd!.POSTED.chiark.greenend.org.uk!not-for-mail From: Theo Newsgroups: sci.electronics.design,comp.sys.raspberry-pi Subject: Re: uP port mapping Date: 12 Sep 2024 17:43:04 +0100 (BST) Organization: University of Cambridge, England Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Info: chiark.greenend.org.uk; posting-host="chiark.greenend.org.uk:93.93.131.173"; logging-data="19970"; mail-complaints-to="abuse@chiark.greenend.org.uk" User-Agent: tin/1.8.3-20070201 ("Scotasay") (UNIX) (Linux/5.10.0-28-amd64 (x86_64)) Originator: theom@chiark.greenend.org.uk ([93.93.131.173]) Bytes: 4711 Lines: 63 In comp.sys.raspberry-pi 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. 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