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

LAB 2A: SIDDHANT MATHUR ( WORKED WITH RUTURAJ A. NANOTI AND ARNAV GADRE) #63

Open
wants to merge 23 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 ESE519-Spreadsheet.xlsx
Binary file not shown.
Binary file added ESE5190-3.7 (2).xlsx
Binary file not shown.
Binary file added Hello_blinken_light.mp4
Binary file not shown.
103 changes: 98 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,102 @@
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
SIDDHANT MATHUR
www.linkedin.com/in/siddhantmathur14
Tested on: HP PAVILION X360, WINDOWS 10 (WSL)



# 3 TALKING LEDs

# 3.2 PIO

Q) Why is bit-banging impractical on your laptop, despite it having a much faster processor than the RP2040?

- PC-class processors keep hundreds of instructions in-flight on a single core at once, which has drawbacks when trying to switch rapidly between hard real time tasks. Thus, bit - banging is impractical on a laptop despite it having much higher processor speeds.

Q) What are some cases where directly using the GPIO might be a better choice than using the PIO hardware?

- A PIO state machine gets a lot more done in one cycle than a Cortex-M0+ when it comes to I/O: for example, sampling a GPIO value, toggling a clock signal and pushing to a FIFO all in one cycle, every cycle. However , a PIO state machine is not remotely capable of running general purpose software.

Q)How do you get data into a PIO state machine?

- The state machine needs to be told which GPIO to output to depending on which pin group would be used ( out pin in this case) . Also , the GPIO needs to be told that the PIO is in control of it. Lastly , make sure that the PIO is driving the output enable line high.

Q)How do you get data out of a PIO state machine?

- The RP2040 has two PIO blocks, each of them with four state machines. Each PIO block has a 32-slot instruction memory which is visible to the four state machines in the block. We need to load our program into this instruction memory before any of our state machines can run the program. Once the program is loaded, we find a free state machine and tell it to run our program.

Q) How do you program a PIO state machine?

- Programming a PIO state machine requires pushing data into the TX FIFO from which it will be transmitted to the state machine and then executed.

Q) 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?

- The function pio_sm_put_blocking() writes data to the TX FIFO queue and blocks it if it is full.

Q)What role does the pioasm “assembler” play in the example, and how does this interact with CMake?

- The assmebler compiles Assembly code into a human readable format. CMake function pico_generate_pio_header(TARGET PIO_FILE) invokes pioasm automatically and adding the generated header to the include path of the target TARGET.

# 3.3 FOLLOW THE FLOW

## ANNOTATIONS FOR ws2812.c

* The code for ```ws2812.c``` has been annotated with comments.

![embedded_c1](https://user-images.githubusercontent.com/114244849/196307976-05af9e2a-d3d2-4847-a077-d6c97631ee3d.JPG)


![embedded_c2](https://user-images.githubusercontent.com/114244849/196308018-2ddacf39-faf4-4dc2-bf59-087eda721dcb.JPG)


![embedded_c3](https://user-images.githubusercontent.com/114244849/196308030-3c1b25bc-5c22-4dd1-a0da-bd543f8170bf.JPG)


![embedded_c4](https://user-images.githubusercontent.com/114244849/196308049-ac4486b3-2af8-4518-99c4-45e7b3e78523.JPG)


![embedded_c5](https://user-images.githubusercontent.com/114244849/196308069-88e2dddb-4e3c-42c7-804f-8d6d05becd84.JPG)



## ANNOTATIONS FOR ws2812.pio.h

* The code for ```ws2812.pio.h``` has been annotated with comments.

![embedded_h1](https://user-images.githubusercontent.com/114244849/196355989-a4ea90cf-5813-4533-aba3-f1060ab84ee2.JPG)

![embedded_h2](https://user-images.githubusercontent.com/114244849/196356067-867041a5-4a26-4be2-bc4c-af5e2e332eb1.JPG)

![embedded_h3](https://user-images.githubusercontent.com/114244849/196356150-34570339-2ca8-42b2-9cd0-c4048fa06903.JPG)

![embedded_h4](https://user-images.githubusercontent.com/114244849/196356241-aa914f54-79a1-4543-a976-7e1c4b70845a.JPG)

![embedded_h5](https://user-images.githubusercontent.com/114244849/196356300-8d6653ef-a938-448f-bf05-5fac8d3a23b3.JPG)


## 3.4 COLOR BY NUMBER

The Excel file containing all the register values can be accessed through the given link: [Excel link](https://github.com/Siddmathur14/ese5190-2022-lab2-into-the-void-star/blob/main/ESE519-Spreadsheet.xlsx)

## 3.5 MODELING TIME

![WhatsApp Image 2022-10-18 at 03 12 39](https://user-images.githubusercontent.com/114244849/196362052-a35447a9-db77-41d2-b68d-aaea8a9abedf.jpeg)


## 3.6 & 3.7 ZOOMING IN AND TIMING DIAGRAM

The Excel File contains timing data for packet transfer to the **ws2812** module :[Excel Link](https://github.com/Siddmathur14/ese5190-2022-lab2-into-the-void-star/blob/main/ESE5190-3.7%20(2).xlsx)

## 4 HELLO BLINKENLIGHT







https://user-images.githubusercontent.com/114244849/196412619-aa4f86cc-6e59-4941-aeed-088d7eb4bb30.mp4


(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.)
52 changes: 52 additions & 0 deletions hello_blinkenlight/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)

project(blink_new C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()

if (TARGET tinyusb_device)
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_include_directories(pio_ws2812 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/ws2812.h)

target_sources(pio_ws2812 PRIVATE ws2812.c ws2812.h)

target_link_libraries(pio_ws2812 PRIVATE pico_stdlib hardware_pio)
pico_add_extra_outputs(pio_ws2812)

pico_enable_stdio_usb(pio_ws2812 1)
pico_enable_stdio_uart(pio_ws2812 0)
# 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)
elseif(PICO_ON_DEVICE)
message(WARNING "not building hello_usb because TinyUSB submodule is not initialized in the SDK")
endif()

114 changes: 114 additions & 0 deletions hello_blinkenlight/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

46 changes: 46 additions & 0 deletions hello_blinkenlight/generated/ws2812.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# -------------------------------------------------- #
# This file is autogenerated by pioasm; do not edit! #
# -------------------------------------------------- #

import rp2
from machine import Pin
# ------ #
# ws2812 #
# ------ #

ws2812_T1 = 2
ws2812_T2 = 5
ws2812_T3 = 3

@rp2.asm_pio(sideset_init=pico.PIO.OUT_HIGH, out_init=pico.PIO.OUT_HIGH, out_shiftdir=1)
def ws2812():
wrap_target()
label("0")
out(x, 1) .side(0) [2] # 0
jmp(not_x, "3") .side(1) [1] # 1
jmp("0") .side(1) [4] # 2
label("3")
nop() .side(0) [4] # 3
wrap()



# --------------- #
# ws2812_parallel #
# --------------- #

ws2812_parallel_T1 = 2
ws2812_parallel_T2 = 5
ws2812_parallel_T3 = 3

@rp2.asm_pio()
def ws2812_parallel():
wrap_target()
out(x, 32) # 0
mov(pins, invert(null)) [1] # 1
mov(pins, x) [4] # 2
mov(pins, null) [1] # 3
wrap()



73 changes: 73 additions & 0 deletions hello_blinkenlight/pico_sdk_import.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake

# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()

if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()

set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")

if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()

if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()

get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()

set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()

set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)

include(${PICO_SDK_INIT_CMAKE_FILE})
Loading