Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iothings:proiecte:2021:zephyr [2022/01/28 14:55]
andrei_edward.popa [3.Drivers Description]
iothings:proiecte:2021:zephyr [2022/01/28 19:20] (current)
andrei_edward.popa [Support for Raspberry Pi Pico in Zephyr RTOS]
Line 3: Line 3:
 All drivers were implemented by Andrei-Edward Popa from ACES Master Program and those are licensed under Apache 2.0 Open Source License. ​ All drivers were implemented by Andrei-Edward Popa from ACES Master Program and those are licensed under Apache 2.0 Open Source License. ​
  
-Project repository: https://​github.com/​andrei-edward-popa/​zephyr/+Project repository: ​[[https://​github.com/​andrei-edward-popa/​zephyr|Andrei-Edward Popa Github Repository]]
  
 Branches: rpi_pico_working_uart,​ rpi_pico_working_i2c Branches: rpi_pico_working_uart,​ rpi_pico_working_i2c
 +
 +Demo: [[https://​www.youtube.com/​watch?​v=IdkH4meemCc|UART and I2C Driver Usage in Zephyr Project for Raspberry Pi Pico Board]]
  
 ==== 1.Project Objective and Description ==== ==== 1.Project Objective and Description ====
Line 14: Line 16:
  
 For me, this was a good start to learning how Zephyr is structured, understand the drivers API and how protocols like UART and I2C work and what registers we can use to make the driver functional. So, my project is about drivers for Raspberry Pi Pico board and how can we implement drivers like UART and I2C in this RTOS called Zephyr. For me, this was a good start to learning how Zephyr is structured, understand the drivers API and how protocols like UART and I2C work and what registers we can use to make the driver functional. So, my project is about drivers for Raspberry Pi Pico board and how can we implement drivers like UART and I2C in this RTOS called Zephyr.
 +
 +I will provide all steps for Zephyr installation and add the support for Raspberry Pi Pico below. All the steps are done in Ubuntu 20.04 LTS Linux Distribution.
 +
 +First we need to install west and all its dependencies.
 +  * sudo apt update
 +  * wget https://​apt.kitware.com/​kitware-archive.sh
 +  * sudo bash kitware-archive.sh
 +  * sudo apt install --no-install-recommends git cmake ninja-build gperf ccache dfu-util device-tree-compiler wget python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev
 +  * pip3 install --user -U west
 +  * echo '​export PATH=~/​.local/​bin:"​$PATH"'​ >> ~/.bashrc
 +  * source ~/.bashrc
 +
 +The next step is to initialize the Zephyr Project, update all hal modules and install the Zephyr SDK.
 +  * west init ~/​zephyrproject
 +  * cd ~/​zephyrproject
 +  * west update
 +  * west zephyr-export
 +  * pip3 install --user -r ~/​zephyrproject/​zephyr/​scripts/​requirements.txt
 +  * pip3 install --user -U docutils==0.16
 +  * pip3 install --user -r ~/​zephyrproject/​zephyr/​scripts/​requirements.txt
 +  * cd ~
 +  * wget https://​github.com/​zephyrproject-rtos/​sdk-ng/​releases/​download/​v0.13.1/​zephyr-sdk-0.13.1-linux-x86_64-setup.run
 +  * chmod +x zephyr-sdk-0.13.1-linux-x86_64-setup.run
 +  * ./​zephyr-sdk-0.13.1-linux-x86_64-setup.run -- -d ~/​zephyr-sdk-0.13.1
 +  * sudo cp ~/​zephyr-sdk-0.13.1/​sysroots/​x86_64-pokysdk-linux/​usr/​share/​openocd/​contrib/​60-openocd.rules /​etc/​udev/​rules.d
 +  * sudo udevadm control --reload
 +  * cd ~/​zephyrproject/​modules/​hal
 +  * git clone https://​github.com/​andrei-edward-popa/​hal_raspberrypi_pico raspberrypi
 +  * cd raspberrypi
 +  * git checkout fix_hardware_pwm_i2c_spi
 +
 +Open ~/.bashrc file and add the following environment variables and then execute bash command.
 +  * export ZEPHYR_BASE=/​home/"​user"/​zephyrproject/​zephyr
 +  * export ZEPHYR_GCC_VARIANT=zephyr
 +  * export ZEPHYR_SDK_INSTALL_DIR=/​home/"​user"/​zephyr-sdk-0.13.1
 +  * export ZEPHYR_TOOLCHAIN_VARIANT="​zephyr"​
 +  * export CMAKE_PREFIX_PATH=/​home/"​user"/​zephyrproject/​zephyr/​share/​zephyr-package/​cmake
 +  * export IDF_PATH="/​home/"​user"/​zephyrproject/​modules/​hal/​raspberrypi"​
 +
 +Finally, add my personal remote to your git local repository.
 +  * cd ~/​zephyrproject/​zephyr
 +  * git remote add "​remote_name"​ https://​github.com/​andrei-edward-popa/​zephyr
 +  * git remote update
 +  * git pull
 +  * git checkout rpi_pico_working_uart OR rpi_pico_working_i2c OR rpi_pico_working_i2c_samples
 +
 +All the steps are tested on a fresh machine and it works without problems. You need to change the "​user"​ with your machine username.
 +
 +
  
 ==== 2.Hardware Description ==== ==== 2.Hardware Description ====
Line 108: Line 159:
 After the API is done, the master mode works. But now, what about the slave mode? As I say previously on this driver, the slave mode cannot work without interrupts because we don't need to poll the device every time to see if his address is on the bus. So, when we configured the device in slave mode, we need to enable all the interrupts and write some Interrupt Service Routine function to handle that interrupt. After the API is done, the master mode works. But now, what about the slave mode? As I say previously on this driver, the slave mode cannot work without interrupts because we don't need to poll the device every time to see if his address is on the bus. So, when we configured the device in slave mode, we need to enable all the interrupts and write some Interrupt Service Routine function to handle that interrupt.
  
-Because we want t+Because we want that ISR to be executed faster, I create some non-blocking read and write function that read data from RX FIFO if it is not empty and write data into the TX FIFO if it is not full. We need to read the interrupt status register to see that interrupt occurs and how to treat it. Now let's discuss what happens when a master device what to read or write to a slave: 
 +  * When a master device sends data to a slave device, the data is stored into the RX FIFO of the slave. We want to trigger an interrupt if at least one character was written. For that, in slave mode, we need to set the depth of the FIFOs to 1. Now, when the master device sends one character, the RX FIFO of the slave is full and we can check the RX_FULL bit from Interrupt Status Register. If we are in that case, we need to read that data with the non-blocking read function and call a callback function provided by the user (we will discuss about that) of the driver to handle that data that just arrives. 
 +  * When a master device wants to read from a slave device, we need to check if the RD_REQ bit (Read Requested) from the Interrupt Status Register is set. If that's the case, we need to clear that interrupt, call a callback function provided by the user to get the value that master needs and write it to the master with the non-blocking write function. 
 +  * If the slave detects a stop bit from master, we can call a callback function provided by the user to stop some configuration for read/write from master. 
 + 
 +The slave callbacks are function provided by the users to instruct the slave device that data to write to a master or what to do with the data that comes from the master device. The API of the slave callbacks is the following:​ 
 +  * write_requested:​ Function called when a write to the device is initiated. 
 +  * read_requested:​ Function called when a read from the device is initiated. 
 +  * write_received:​ Function called when a write to the device is continued. 
 +  * read_processed:​ Function called when a read from the device is continued. 
 +  * stop: Function called when a stop condition is observed after a start condition addressed to a particular device. 
 + 
 +Anytime when we want to use the Raspberry Pi Pico board as an I2C slave, we need to provide those callback functions (maybe not all) for dealing this data read and write from or to a slave.
  
  
iothings/proiecte/2021/zephyr.1643374537.txt.gz · Last modified: 2022/01/28 14:55 by andrei_edward.popa
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0