Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suraj Sree Balakrishna Marthy worked with Sai Koushik S S #80

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added 3.3 AnnotatedCode.pdf
Binary file not shown.
Binary file added 3.4 Lab2.xlsx
Binary file not shown.
Binary file added 3.7 lab2.xlsx
Binary file not shown.
Binary file added Part 3.5suraj.pdf
Binary file not shown.
81 changes: 75 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,78 @@
University of Pennsylvania, ESE 5190: Intro to Embedded Systems, Lab 2A
University of Pennsylvania, ESE 5190 : Intro to Embedded Systems, Lab 2A

(TODO) YOUR NAME HERE
(TODO) LinkedIn, personal website, twitter, etc.
Tested on: (TODO) MacBook Pro (14-inch, 2021), macOS Monterey 12.5.1
SURAJ SREE BALAKRISHNA MARTHY
https://www.linkedin.com/in/suraj-marthy-8b7109138/ ;
Tested on: Acer Predator Helios 300 PH315-51 (15.6 inches, Intel Core i5+8th Gen), Windows 11

## 3.2 : Reading Questions

- Why is bit-banging impractical on your laptop, despite it having a much faster processor than the RP2040?
- Bit banging causes errors in communication basically during read/write. Anything that repeatedly reads/writes from GPIOs may not use bit-banging and preferably PIO may be used. Even though a laptop has high processing power than the RP2040, obtaining a precise timing is tricky for real time applications. But this can be performed on an RP2040 due to the presence of a dedicated hardware called PIO.

- What are some cases where directly using the GPIO might be a better choice than using the PIO hardware?
- GPIO can be better when the timing precision may be compromised. PIO is used when there is repeated read/write of information with a great deal of accuracy in time. For example, in case of a feedback controlled loop system (closed loop) the GPIO might just be sufficient.

- How do you get data into a PIO state machine?
- Data can be put in a PIO state machine through a FIFO queue. FIFO queues interact with the state machine to transmit and receive data from the main program. Helper functions such as pio_sm_put_blocking() can be used to indicate that the FIFO is full and to wait until it gets free.

- How do you get data out of a PIO state machine?
- An "out" statement can be used in a PIO code to write the data to a particular PIN which is defined. Basically, instead of FIFO PUSH from the above case, it works as FIFO PULL.

- How do you program a PIO state machine?
- A .pio file is used to program a PIO state machine which contains instructions to identify each PIN behaviour. After the PIN behaviours are programmed, the configuration of the state machine is added and the CMakeLists.txt file is edited to generate a .pio.h file which is included in the C code to transmit data to the SM.

- In the example, which low-level C SDK function is directly responsible for telling the PIO to set the LED to a new color? How is this function accessed from the main “application” code?
- pio_sm_put_blocking() is a helper function that is used to block the FIFO queue if it is full and also to wrte data to the TX FIFO queue if it is vacant. So this means that the same function is used to tell the PIO to set the LED to a new color.

- What role does the pioasm “assembler” play in the example, and how does this interact with CMake?
- The assembly C code is described in a easier way using the pioasm assembler. pico_generate_pio_header has to be called in the CMake file to create a header file which invokes pioasm.

## 3.3 : Follow the Flow

This [link](https://github.com/SurajMarthy1001/ese5190-2022-lab2-into-the-void-star/blob/cc6a997b7032aff321ef1062485155c75cc8570c/3.3%20AnnotatedCode.pdf) contains the annotated code of ws2812.c and generated/ws2812.pio.h

## 3.4 : Color by Number

This[3.4 Lab2.xlsx](https://github.com/SurajMarthy1001/ese5190-2022-lab2-into-the-void-star/files/9810321/3.4.Lab2.xlsx)
contains the spreadsheet of initial registers

## 3.5 : Modeling Time
[Part 3.5suraj.pdf](https://github.com/SurajMarthy1001/ese5190-2022-lab2-into-the-void-star/files/9810326/Part.3.5suraj.pdf)

This contains paper model of SM's operation as it relays a color packet to the Neopixel

## 3.6 & 3.7 : Zooming In & Timing Diagram
[3.7 lab2.xlsx](https://github.com/SurajMarthy1001/ese5190-2022-lab2-into-the-void-star/files/9810322/3.7.lab2.xlsx)

This contains timing diagram

## 4 : Hello, Blinkenlight

This [link](https://github.com/SurajMarthy1001/ese5190-2022-lab2-into-the-void-star/tree/main/ledhello) directs to the folder that has the code and header files needed to blink the Neopixel when a certain Serial output is seen


https://user-images.githubusercontent.com/69215958/196429128-bab8395d-db65-49f4-9a87-8242302f350f.mp4



## Decisions Taken

- This lab was performed after going through several documents and online examples on how a PIO and state machine works.
- The readings provided were really useful in understanding the code and different functions that were used in it :

- https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf
- https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf
- https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf

## Reflections

- What were some strengths/weaknesses of working with paper?
- Analysis of the C code and the .pio.h file while understanding the flow of each instruction is easier through annotating on paper.

- What were some strengths/weaknesses of working with spreadsheets?
- Spreadsheets help in better organisation of data and make it easier to read which is one of the main strenghts.

- How might you approach this task using other tools available to you?
- Need to delve deeper into the readings to have a clearer understanding about what exactly is going on.

(TODO: Your README)

Include lab questions, screenshots, analysis, etc. (Remember, this is public, so don't put anything here you don't want to share with the world.)
45 changes: 45 additions & 0 deletions ledhello/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.16)
#include(pico_sdk_import.cmake)
#project(lab2 C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()

add_executable(pio_ws2812)

# generate the header file into the source tree as it is included in the RP2040 datasheet
pico_generate_pio_header(pio_ws2812 ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated)

target_sources(pio_ws2812 PRIVATE ws2812.c)

target_link_libraries(pio_ws2812 PRIVATE pico_stdlib hardware_pio)
pico_add_extra_outputs(pio_ws2812)

# add url via pico_set_program_url
#example_auto_set_url(pio_ws2812)

add_executable(pio_ws2812_parallel)

pico_generate_pio_header(pio_ws2812_parallel ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated)

target_sources(pio_ws2812_parallel PRIVATE ws2812_parallel.c)

target_compile_definitions(pio_ws2812_parallel PRIVATE
PIN_DBG1=3)

target_link_libraries(pio_ws2812_parallel PRIVATE pico_stdlib hardware_pio hardware_dma)
pico_add_extra_outputs(pio_ws2812_parallel)

# add url via pico_set_program_url
#example_auto_set_url(pio_ws2812_parallel)

# Additionally generate python and hex pioasm outputs for inclusion in the RP2040 datasheet
add_custom_target(pio_ws2812_datasheet DEPENDS ${CMAKE_CURRENT_LIST_DIR}/generated/ws2812.py)
add_custom_command(OUTPUT ${CMAKE_CURRENT_LIST_DIR}/generated/ws2812.py
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio
COMMAND Pioasm -o python ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio ${CMAKE_CURRENT_LIST_DIR}/generated/ws2812.py
)
add_dependencies(pio_ws2812 pio_ws2812_datasheet)

pico_enable_stdio_usb(pio_ws2812 1)
pico_enable_stdio_uart(pio_ws2812 0)
Binary file added ledhello/Neopixel_blinks.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions ledhello/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## C code complied:

![image](https://user-images.githubusercontent.com/69215958/196338392-66380958-75b1-4972-a331-57a95f6aba72.png)

## Code Built:

![image](https://user-images.githubusercontent.com/69215958/196338358-194a5ad1-ddf8-4a28-bfa7-b2ece48919fc.png)

## Output:

![image](https://user-images.githubusercontent.com/69215958/196338333-68f1fc47-7ddf-4182-8e9e-d2c67c11baf5.png)
95 changes: 95 additions & 0 deletions ledhello/adafruit_qtpy_rp2040.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

// -----------------------------------------------------
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
// -----------------------------------------------------

#ifndef _BOARDS_ADAFRUIT_QTPY_RP2040_H
#define _BOARDS_ADAFRUIT_QTPY_RP2040_H

// For board detection
#define ADAFRUIT_QTPY_RP2040

// On some samples, the xosc can take longer to stabilize than is usual
#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
#endif

//------------- UART -------------//
#ifndef PICO_DEFAULT_UART
#define PICO_DEFAULT_UART 1
#endif

#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 20
#endif

#ifndef PICO_DEFAULT_UART_RX_PIN
#define PICO_DEFAULT_UART_RX_PIN 5
#endif

//------------- LED -------------//
// No normal LED
// #define PICO_DEFAULT_LED_PIN 13

#ifndef PICO_DEFAULT_WS2812_PIN
#define PICO_DEFAULT_WS2812_PIN 12
#endif

#ifndef PICO_DEFAULT_WS2812_POWER_PIN
#define PICO_DEFAULT_WS2812_POWER_PIN 11
#endif

//------------- I2C -------------//
#ifndef PICO_DEFAULT_I2C
#define PICO_DEFAULT_I2C 0
#endif

#ifndef PICO_DEFAULT_I2C_SDA_PIN
#define PICO_DEFAULT_I2C_SDA_PIN 24
#endif

#ifndef PICO_DEFAULT_I2C_SCL_PIN
#define PICO_DEFAULT_I2C_SCL_PIN 25
#endif

//------------- SPI -------------//
#ifndef PICO_DEFAULT_SPI
#define PICO_DEFAULT_SPI 0
#endif

#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN 3
#endif

#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN 4
#endif

#ifndef PICO_DEFAULT_SPI_SCK_PIN
#define PICO_DEFAULT_SPI_SCK_PIN 6
#endif

//------------- FLASH -------------//

#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1

#ifndef PICO_FLASH_SPI_CLKDIV
#define PICO_FLASH_SPI_CLKDIV 2
#endif

#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)
#endif

// All boards have B1 RP2040
#ifndef PICO_RP2040_B0_SUPPORTED
#define PICO_RP2040_B0_SUPPORTED 0
#endif

#endif
Binary file added ledhello/built.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ledhello/compiled.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
114 changes: 114 additions & 0 deletions ledhello/generated/ws2812.pio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //

#pragma once

#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif

// ------ //
// ws2812 //
// ------ //

#define ws2812_wrap_target 0
#define ws2812_wrap 3

#define ws2812_T1 2
#define ws2812_T2 5
#define ws2812_T3 3

static const uint16_t ws2812_program_instructions[] = {
// .wrap_target
0x6221, // 0: out x, 1 side 0 [2]
0x1123, // 1: jmp !x, 3 side 1 [1]
0x1400, // 2: jmp 0 side 1 [4]
0xa442, // 3: nop side 0 [4]
// .wrap
};

#if !PICO_NO_HARDWARE
static const struct pio_program ws2812_program = {
.instructions = ws2812_program_instructions,
.length = 4,
.origin = -1,
};

static inline pio_sm_config ws2812_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap);
sm_config_set_sideset(&c, 1, false, false);
return c;
}

#include "hardware/clocks.h"
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = ws2812_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}

#endif

// --------------- //
// ws2812_parallel //
// --------------- //

#define ws2812_parallel_wrap_target 0
#define ws2812_parallel_wrap 3

#define ws2812_parallel_T1 2
#define ws2812_parallel_T2 5
#define ws2812_parallel_T3 3

static const uint16_t ws2812_parallel_program_instructions[] = {
// .wrap_target
0x6020, // 0: out x, 32
0xa10b, // 1: mov pins, !null [1]
0xa401, // 2: mov pins, x [4]
0xa103, // 3: mov pins, null [1]
// .wrap
};

#if !PICO_NO_HARDWARE
static const struct pio_program ws2812_parallel_program = {
.instructions = ws2812_parallel_program_instructions,
.length = 4,
.origin = -1,
};

static inline pio_sm_config ws2812_parallel_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + ws2812_parallel_wrap_target, offset + ws2812_parallel_wrap);
return c;
}

#include "hardware/clocks.h"
static inline void ws2812_parallel_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
for(uint i=pin_base; i<pin_base+pin_count; i++) {
pio_gpio_init(pio, i);
}
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true);
pio_sm_config c = ws2812_parallel_program_get_default_config(offset);
sm_config_set_out_shift(&c, true, true, 32);
sm_config_set_out_pins(&c, pin_base, pin_count);
sm_config_set_set_pins(&c, pin_base, pin_count);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_parallel_T1 + ws2812_parallel_T2 + ws2812_parallel_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}

#endif

Loading