This tutorial is on "Interfacing Rpi SenseHAT with AMD-Xilinx Kria KR260 and Petalinux".
Tools Used on this Tutorial are:
- Vivado 2022.2
- Petalinux 2022.2
The VIVADO/Petalinux project source, BSP, Kria Firmware of Rpi-SenseHAT is available at Github: https://github.com/LogicTronix/KR260-SenseHAT-Petalinux [Git Branch: SenseHAT-Sensors]Raspberry Pi Sense HAT
The Raspberry Pi Sense HAT is an add-on board that gives an array of sensing capabilities. The on-board sensors allow us to monitor pressure, humidity, temperature, color, orientation, and movement. The 8x8 RGB LED matrix allows us to visualize data from the sensors, and the five-button joystick can act as an input device.
All the sensors on the board are connected to a single I2C bus. All the sensors act as a slave and use the I2C protocol to communicate with the master.
ICs used on the Sense Hat:
Following are the IPs Cores used in the Vivado design for creating this "Sense HAT- I2C interface" working on Kria KR260.
Zynq® Ultrascale+™ MPSoCThe Zynq® Ultrascale+™ MPSoC acts as a logic connection between the PS and the PL while assisting to integrate custom and embedded IPs with the processing system using the Vivado® IP integrator.
AXI Interrupt ControllerThe AXI Interrupt Controller (AXI INTC) core concentrates multiple interrupt inputs from peripheral devices to a single interrupt output to the system processor.
Clocking WizardThe Clocking Wizard IP simplifies the creation of HDL source code wrappers for clock circuits customized to user clocking requirements. The Wizard guides users in setting the appropriate attributes for your clocking primitive, and allows to override any wizard-calculated parameter.
AXI IIC Bus InterfaceThe AXI IIC Bus Interface connects to the AMBA® AXI specification and provides a low-speed, two-wire, serial bus interface to a large number of popular devices. This product specification defines the architecture, hardware (signal) interface, software (register) interface, and parameterization options for the AXI IIC Bus Interface module.
Processing System ResetThe Processing System Reset is a soft IP that provides a mechanism to handle the reset conditions for a given system. The core handles numerous reset conditions at the input and generates appropriate resets at the output. This core generates the resets based upon external or internal reset conditions.
AXI InterconnectThe AXI Interconnect IP connects one or more AXI memory-mapped Master devices to one or more memory-mapped Slave devices. The AXI Interconnect core allows any mixture of AXI master and slave devices to be connected to it, which can vary from one another in terms of data width, clock domain and AXI sub-protocol (AXI4, AXI3, or AXI4-Lite).
Block Design-Complete block designThe Sense HAT sits over the RPi header on the KR260 as shown in the picture above. The description of the 40 pins is shown for this alignment. The sensors communicate over I2C which uses pins 3 and 5.
ConstraintingOnly 2 pins (AE14 and AE15) on the KR260 require constraining for I2C to work. AE15 is used for SDA and AE14 is used for SCL.
set_property PACKAGE_PIN AE15 [get_ports {iic_sda_io}]
set_property IOSTANDARD LVCMOS33 [get_ports {iic_sda_io}]
set_property PULLUP true [get_ports {iic_sda_io}]
set_property PACKAGE_PIN AE14 [get_ports {iic_scl_io}]
set_property IOSTANDARD LVCMOS33 [get_ports {iic_scl_io}]
set_property PULLUP true [get_ports {iic_scl_io}]
However, the following image can be used as a reference to map and constrain all other pins.
- From the File menu, select Export > Export Platform.
- Select the Hardware option in the Platform Type window.
- Select the Pre-Synthesis state and also select the Include bitstream option in the Platform State window.
- Change required Platform Properties.
- Enter a name for the XSA and select a folder to export the XSA to and select Finish.
For integrating SenseHAT sensors we have to have Petalinux driver or linux driver of those sensors. For SenseHAT, C/C++ Drivers for most sensors are available from the vendor themselves. Some drivers are also written by independent developers.
Humidity/Temperature
Accelerometer/Gyroscope and Magnetometer
Pressure/Temperature
- https://github.com/ameltech/sme-lps25h-library
- https://github.com/kirananto/RaZorReborn/tree/master/drivers/sensors/pressure/lps25h
LED Driver
Petalinux Development:PrerequisitesCreating a petalinux project requires a supported BSP which can be downloaded from the link below. A project also can be created without the BSP which is less convenient.
- Download the supported BSP for the board from Xilinx downloads.
- Download link: https://www.xilinx.com/member/forms/download/xef.html?filename=xilinx-kr260-starterkit-v2022.2-10141622.bsp
Steps to create a petalinux project are listed below.
● Create a folder and copy the platform (XSA) exported from Vivado.
● Also copy the BIN file generated by Vivado located in <VIVADO_PROJECT_DIR>/<DESIGN_NAME>.runs/impl_1/<DESIGN_WRAPPER_NAME>.bin
● Open a terminal in the directory and source the petalinux script.
● Run the command below to create a petalinux project named <project-name>.
petalinux-create --type project -s <location-to-bsp> --name <project-name>
● Run the command below to configure the project.
petalinux-config --get-hw-description <path-to-xsa/xsa-dir>
● In the project configuration window,
○ Enable FPGA Manager under FPGA Manager.
- Under Image Packaging Configuration,
- Change Root filesystem type to INITRD
- Change INITRAMFS/INITRD Image name to petalinux-initramfs-image
- Disable Copy final images to tftpbootUnder Image Packaging Configuration,
- Save and exit the configuration window.
- Run the following to configure the kernel.
petalinux-config -c kernel
- Under Device Drivers > I2C support > I2C Hardware Bus support, enable
- Cadence I2C Controller
- Xilinx I2C Controller
- Save and exit the configuration.
- Run the following to configure the root filesystem.
petalinux-config -c rootfs
- Under Filesystem Packages > base > i2c-tools, enable
- i2c-tools
- i2c-tools-dev
- Under Filesystem Packages > misc > python3, enable
- python3
- All other python modules that you require
- Save and exit the configuration.
- Run petalinux-build to build the project.
- Run the following command to create a bootable WIC image.
petalinux-package --wic --images-dir images/linux/ --bootfiles "ramdisk.cpio.gz.u-boot, boot.scr, Image, system.dtb, system-zynqmp-sck-kr-g-revB.dtb" --disk-name "sda"
- Make sure the dtb file is present in the <petalinux-project-dir>/images/linux/ directory.
- Download, install and run BalenEtcher.
- Locate the WIC image in images/linux directory.
- Select the target device and select Flash.
Generating Device Tree Overlay
- Open a terminal, in the directory where the XSA was copied. Source Petalinux again here and run the xsct command.
- If the system cannot find the xsct command, make sure to source the Vitis or PetaLinux shell script.
- If the xsct command is still missing after running the Petalinux shell script, run the following command.
PATH="${XSCT_TOOLCHAIN}/bin:${PATH}"
- Running the following “HSI” command will extract the contents of the XSA in the current directory.
hsi::open_hw_design ./<xsa-name>.xsa
createdts -hw ./<xsa-name>.xsa -zocl -platform-name <any-platform-name> -git-branch <git-branch> -overlay -compile -out ./<any-non-existing-dir-name-is-better>
- Running the above command will:
- Clone the branch <git-branch> from the Xilinx device tree generator repo
- Generate the device tree (pl.dtsi) in./<any-non-existing-dir-name-is-better>/<any-non-existing-dir-name-is-better>/<any-platform-name>/psu_cortexa53_0/device_tree_domain/bsp/ directory
- Exit the xsct shell.
Note: The following command can be run in a regular terminal without Petalinux script sourced.
- Run the following command to compile the device tree.
dtc -@ -O dtb -o ./kr260.dtbo ./kr260_dt/kr260_dt/kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi
- Make sure to edit the path to the pl.dtsi.
- This command will generate kr260.dtbo in the current directory.
- If dtc throws “dtc: invalid option -- '@'” error, you will need to compile dtc yourself.
Compiling DTC
- Run the following commands.
git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git
cd dtc
make
- If you encounter ‘cc1: all warnings being treated as errors’, edit the Makefile in the dtc directory and remove the -Werror flag from CFLAGS.
make install
- Running the above command will install dtc in $HOME/bin..
Retrying to Compile the Device Tree
- Run cd../ to move out of the dtc directory
- dtc -@ -O dtb -o./kr260.dtbo./kr260_dt/kr260_dt/kr260/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi
Transferring the Files to the Device
- Run the following command to create shell.json.
echo '{ "shell_type" : "XRT_FLAT", "num_slots": "1" }' > shell.json
- Rename the bin file from the Vivado implementation directory the same as you named the dtbo.
- I have renamed them to kr260.bit.bin and kr260.dtbo.
- Connect the Sense HAT to the KR260 header.
- Boot the device now and login.
- The username and password is petalinux by default.
- Create a directory in the device home directory.
mkdir ~/<any-directory-name>
- Connect your device to your router and find the ip address by running the ifconfig command. Better if you assign a static IP for the device in your router settings.
- Run the scp command on the host machine to transfer the files to the device.
scp ./kr260.bit.bin ./kr260.dtbo ./shell.json petalinux@<DEVICE_IP>:~/<directory-you-created-earlier>
- Move the directory that contains the kr260.bit.bin, kr260.dtbo and shell.json to /lib/firmware/xilinx/.
sudo mv ./<directory-you-created-earlier> /lib/firmware/xilinx/
- List the apps present on the device.
sudo xmutil listapps
- Unload the current app.
sudo xmutil unloadapp
- Load your app (kr260 in this case).
sudo xmutil loadapp kr260
- Check if the XIIC is listed as an I2C bus in the system.
i2cdetect -l
- This will list all I2C bus in the system (i2c-7 in this case).
- Check for devices on the XIIC bus.
I2cdetect -y -r <i2c-bus-number>
- This will show the address of the sensors connected to the I2C bus.
- If the Sense Hat is working, it should show the following addresses.
- The following address map of I2C bus 7 shows all the sensor addresses from the Sense HAT. These addresses are also listed in table 1.
To communicate with the sensors attached to the bus with python, a python package needs to be installed.
Installing pip, the Package Installer for PythonTo install the required packages, pip is required. And since petalinux does not have an option to enable pip, it should be installed manually.
Thankfully, it is very easy to install pip. Follow the following steps.
- Run any of the following commands in a terminal to download the get-pip.py python script.
wget https://bootstrap.pypa.io/get-pip.py
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
- Run python get-pip.py and wait for it to finish.
- Run python3 get-pip.py if the above command did not work.
To install SMBus, run pip install smbus. SMBus provides python bindings for Linux SMBus access through i2c-dev.
Writing a crude python applicationTo communicate with the sensors, we require an object of the SMBus class that provides us with various functions that make communicating easier. We create a new instance of the SMBus class by passing the I2C bus number that our sensors are attached to.
bus = smbus.SMBus(<i2c-bus-number>)
With the bus object, we can access the following functions that help us read/write data from/to the sensor registers.
To get data from the sensors, we write specific byte data to the control registers that will enable/disable certain functionality in the device. The most important step is to put the sensors into active mode which will start sensing and store the results in its internal registers. We can then read these registers and do calculations with calibration data that are also stored in other registers.
The calibration data is stored in an internal non-volatile memory and is written to calibration registers at power-on.
For details about the registers and their description, please check the datasheet for the sensors.Generic Way to Communicate with the Sensors
All sensors on the device follow a similar method for configuration and calibration.
- Set output data rate and averaging
- Output data rate specifies the frequency at which the output data is updated
- Averaging gives an average of selected number of samples
- Activate the sensor
- Read and store the calibration data
- Read the output values and apply the calibration
# HTS221 Sensor Initialization
def HTS221_Init():
temp = bus.read_byte_data(HTS221_ADDRESS, HTS221_CTRL1)
temp |= HTS221_CTRL1_MASK
bus.write_byte_data(HTS221_ADDRESS, HTS221_CTRL1, temp)
# Reading Temperature from Sensor
def HTS221_T_ReadTemp():
buffer = bus.read_i2c_block_data(HTS221_ADDRESS, HTS221_T0_C_8 | 0x80, 2)
tmp = bus.read_byte_data(HTS221_ADDRESS, HTS221_T1_T0)
T0_degC_x8_u16 = ((tmp & 0x03) << 8) | buffer[0]
T1_degC_x8_u16 = ((tmp & 0x0C) << 6) | buffer[1]
T0_degC = twos_complement(bin_str((T0_degC_x8_u16 >> 3), 16), 16)
T1_degC = twos_complement(bin_str((T1_degC_x8_u16 >> 3), 16), 16)
buffer = bus.read_i2c_block_data(HTS221_ADDRESS, HTS221_T0_OUT | 0x80, 4)
T0_out = twos_complement(bin_str(((buffer[1] << 8) | buffer[0]), 16), 16)
T1_out = twos_complement(bin_str(((buffer[3] << 8) | buffer[2]), 16), 16)
buffer = bus.read_i2c_block_data(
HTS221_ADDRESS, HTS221_TEMP_OUT_L | 0x80, 2)
T_out = twos_complement(bin_str(((buffer[1] << 8) | buffer[0]), 16), 16)
temperature = (T_out - T0_out) * (T1_degC - T0_degC) / \
(T1_out - T0_out) + T0_degC
return temperature
Output from the SensorsTemperature and Humidity reading from the HTS221 sensor
Temperature and Pressure reading from the LPS25H sensor
Acceleration, Magnetometer and Gyroscope reading from the LSM9DS1 sensor
For VIVADO, Petalinux project source and Python source code of this tutorial, check: Github [Git Branch: SenseHAT-Sensors]
You can clone Git Branch by following command on your PC:
git clone -b SenseHAT-Sensors https://github.com/logictronix/kr260-sensehat-petalinux
Thanks to Frank Shrestha [frank_shrestha@logictronix.com] for creating this "in-depth" tutorial!
Comments
Please log in or sign up to comment.