PYNQ Input/Output (I/O)
The PYNQ board has a number of sensors (buttons, switches) and actuators (LEDs), as well as a number of general-purpose input/output (I/O) (GPIO) pins.
The hardware I/O pins include the Rasberry PI and Arduino headers.
- The 4 green LEDs (LD0..LED3) and 2 color LEDs (LD4-5R/G/B) are output pins.
- The buttons (BTN0..BTN3) and switches (SW0..SW1) are input pins.
- The Arduino hearder contains 14 digital I/O pins (AR0..AR13) that can be individually set to input or output, as well as 6 analog input pins (A0..A5). Two I/O pins (AR_SCL and AR_SDA) are pins for the I2C (Inter-Integrated Circuit) protocol.
- The Raspberry PI hearder contains 26 I/O pins that can be individually set to input or output. (Some of the pins are hardwired to ground or are not connected, and cannot be routed to/from the switchbox.)
The display PCB pins A0-A5 hides most pins but A0-A5 can still be used through the display PCB:
The I/O pins are usually used with a number of different communication protocols, which the 5EWC0-2023 SD-card image therefore has dedicated hardware modules for. In particular, the following modules are supported:
- interrupt
- UART (2x)
- SPI (2x)
- I2C (2x)
- I2S
- PWM (5x)
- ADC
To connect the different modules to the different sensors, actuators, and I/O pins the 5EWC0-2023 SD-card image contains a switchbox that is programmed using the libpynq library.
Raspberry PI header
To use a Raspberry PI header on the PYNQ board, look up its number (e.g. 7) and then prepend IO_RBPI
.
Note that you need to prepend 0 for pins 1-9, e.g. IO_RBPI07
.
See pinmap.h
in the libpynq documentation for the Raspberry Pi pins (IO_RBPI*).
See Section 18 in the pynq user documentation for more information.
Pmod A header
Six of the Raspberry Pi pins are connected to the Pmod A pins.
Pins 5 & 11 (shown below) are ground:
See pinmap.h
in the libpynq documentation for the Pmod A pins (IO_PMODA*).
See Section 16 in the pynq user documentation for more information.
Note that these pins are not connected by the protection shield in the course. Be aware of the current supplied or received on these pins as not to damage them.
Arduino header
See pinmap.h
in the libpynq documentation for the Arduino pins (IO_A*
and IO_AR*
).
See Section 17 in the pynq user documentation for more information.
Switchbox
The 5EWC0-2023 SD-card image contains a switchbox (see the image at the top of the page) that can be programmed to connect components on the PYNQ board to the hardware input/output pins on the PYNQ board.
pinmap.h
in the libpynq documentation describes which I/O pins are available as input or output to the switchbox.
switchbox.h
in the libpynq documentation describes which hardware modules are available as input or output to the switchbox.
The switchbox can be programmed to set the status of I/O pins to input or output, and to connect the devices to I/O pins. For example, to connect the UART0 RX pin to AR0:
After programming the switchbox, the various sensors, actuators, and communication modules (described next) can be used.
UART (Universal Asynchronous Receiver-Transmitter) protocol
The SD-card image 5EWC0-2023 offers two UARTs (called UART0 and UART1, or numbered 0 and 1). As described in the UART library documentation in the libpynq documentation you can send and receive bytes with high-level UART functions. The UART must first be connected to the appropriate I/O pins (for example using Pmod A, shown below) and initialised.
GPIO and Parallel Communication
IO pins can be set to be input or output, and an output pin on one PYNQ board can be directly connected to an input pin on another PYNQ board. (The boards must always be grounded.) See the GPIO library documentation in the libpynq documentation.
// set pin A0 to be an input pin to be able to read from it
gpio_set_direction(IO_A0, GPIO_DIR_INPUT);
// alternatively, set A0 to be an output pin to be able to write to it
gpio_set_direction(IO_A0, GPIO_DIR_OUTPUT);
// set LED 0 as output and turn it on
gpio_set_direction(IO_LD0, GPIO_DIR_OUTPUT);
gpio_set_level(IO_LD0, GPIO_LEVEL_HIGH);
Note the black wire to ground the boards via the Pmod A pin 11 (see Pmod above).
PWM (Pulse-Width Modulation)
The SD-card image 5EWC0-2023 offers five PWM modules (called PWM0..4, or numbered 0..4). As described in the PWM library documentation in the libpynq documentation you can set and get (read) period, duty cycle, and steps for each PWM.
The PWM must first be connected to the appropriate LEDs or I/O pins and initialized. Take note of which pins to use when using the submodule and protection shield as mentioned in submodule section.
The period and duty cycles of the PWM signal can be selected is a multiple of a single interal clk duration which is 10 nano seconds. This means that a PWM of 100 kHz has a period argument of 1000. The duty cycle is not in percentage but in time, if you want a 50% duty cycle on a 100 kHz signal then it would be 500 times the internal clk, for example:
switchbox_set_pin(IO_AR0, PWM0); //Set PWM0 to arduino pin 0
pwm_init(PWM0,1000); //give it a period of 1000 * 10e-9 seconds.
pwm_set_duty_cycle(PWM0,500); //give it a duration of 500 * 10e-9 seconds
See for an example the following output:
Make sure to pwm_destroy()
at the end of your program as the c script will initialize the signal generator which will run independ from program execution so if you do not destroy the signal pwm instance, it will keep providing a pwm after exiting the program.
I2C or IIC (Inter-Integrated Circuit) protocol
IIC is supported as of libpynq version 5EWC0-2023-v0.2.6. As described in the IIC library documentation in the libpynq documentation you can send and receive bytes with high-level IIC functions. The IIC must first be connected to the appropriate I/O pins. Three examples are shown below.
One master, one slave using Pmod A
One master, two slaves using Pmod A
The Pmod A pins are good to use since they have a built-in 2K2 pull-up resistor, which will work for up to three IICs (one master, two slaves, as shown below). If you want to use more than three IICs then you can use different pins with an external 2K2 pull-up resistor, which should work for more than three boards.
One master, one slave using the IIC pins on the Arduino header
Yellow and green wires connect to the SDL and SDA Arduino pins, respectively. The blue wire is the ground, using the Pmod A ground pin.
I2S or IIS (Inter-IC Sound) protocol
⚠️ Warning The I2S protocol is currently not supported by libpynq (including the latest version 5EWC0-2023-v0.2.6).
Uses the AR_MISO, AR_MOSI pins on the Arduino header. The I2S must first be connected to the appropriate I/O pins and initialised.
SPI (Serial Peripheral Interface) protocol
⚠️ Warning The SPI protocol is currently not supported by libpynq (including the latest version 5EWC0-2023-v0.2.6).
The two SPI modules do not use the SS, SCL, MISO, and MOSI pins on the Arduino header.
Use the switchbox to route the pins of SPI0 and SPI1 to appropriate I/O pins (e.g. switchbox_set_pin(IO_AR0, SWB_SPI0_SS);
).
The SPI must first be connected to the appropriate I/O pins and initialised.