diff --git a/CMakelist.txt b/CMakelist.txt
new file mode 100644
index 0000000..f800181
--- /dev/null
+++ b/CMakelist.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.13)
+include(pico_sdk_import.cmake)
+project(test_project C CXX ASM)
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
+pico_sdk_init()
+
+if (TARGET tinyusb_device)
+ add_executable(hello_pio_usb)
+
+pico_generate_pio_header(hello_pio_usb ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated)
+
+
+ #pull in common dependencies
+ target_sources(hello_pio_usb PRIVATE ws2812.c ws2812.h hello_usb.c ws2812.pio)
+ # pull in common dependencies
+ target_link_libraries(hello_pio_usb pico_stdlib hardware_pio )
+
+ # enable usb output, disable uart output
+ pico_enable_stdio_usb(hello_pio_usb 1)
+ pico_enable_stdio_uart(hello_pio_usb 0)
+
+ # create map/bin/hex/uf2 file etc.
+ pico_add_extra_outputs(hello_pio_usb)
+
+ # add url via pico_set_program_url
+elseif(PICO_ON_DEVICE)
+ message(WARNING "not building hello_usb because TinyUSB submodule is not initialized in the SDK")
+endif()
diff --git a/README.md b/README.md
index a8be84b..d40ddaf 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,98 @@
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
+ Zihan Zhang
+ zihanzh@seas.upenn.edu
+ Tested on: Ubantu
+
+#Part 3.2
+
+ Why is bit-banging impractical on your laptop, despite it having a much faster processor than the RP2040?
+ If the processor is interrupted to attend to one of the hard peripherals it is also responsible for, it can be fatal to the timing of any bit-banged protocol. And
+ the ratio between the processor speed and protocol speed is big, so the processor will spend uselessly idling in between GPIO accesses.
+
+ What are some cases where directly using the GPIO might be a better choice than using the PIO hardware?
+ The main case where software GPIO access is the best choice is LEDs and push buttons.
+
+ How do you get data into a PIO state machine?
+ Use pio_sm_put_blocking() function to push data directly into the state machine’s TXFIFO.
+
+ How do you get data out of a PIO state machine?
+ Use pull instruction first to take one data item from the transmit FIFO buffer, and places it in the output shift register (OSR). Then use out instruction to
+ write that data to some pins.
+
+ How do you program a PIO state machine?
+ System software loads data into the PIO's instruction memory and then set the i/o mapping.
+
+ 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 pio_sm_put_blocking() is called with the parameters from the put_pixel().
+
+ What role does the pioasm “assembler” play in the example, and how does this interact with CMake?
+ Our program written in C language can be built to assembler with GCC. We can use CMake to generate uf2 file which can be recognized by the board.
+
+#Part3.3
+
+ I put this document in part3.3.pdf
+
+
+
+
+
+
+
+
+
+#Part3.4
+
+ I put this document in part3.4.xlsx
+
+#Part3.5
+
+ I put this document in part3.5.pdf
+
+ ![image](https://user-images.githubusercontent.com/114272466/196425034-956fe653-a823-48e1-892a-41bf81dc413c.png)#Part3.5
+
+#Part3.6
+
+ I put this document in part3.6.xlsx
+
+#Part3.7
+
+ I put this document in part3.7.pdf
+ ![image](https://user-images.githubusercontent.com/114272466/196425697-8027d36a-c7af-4fa4-a831-07cd2b553ab0.png)
+
+#Part4 Hello_world
+ ![image](https://user-images.githubusercontent.com/114272466/196427660-26ddf1e4-1cd5-432a-9c07-fa4104f092fe.png)
+
+ For this project, I add the gpio in hello_usb.c and add ws2812.h. At the mean time, I add the fuction in ws2812.c.
+ Additionally, I mix two CMakelists.txt into one doucment. Finally, I made it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-(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.)
diff --git a/hello_usb.c b/hello_usb.c
new file mode 100644
index 0000000..67e8cdd
--- /dev/null
+++ b/hello_usb.c
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include
+
+#include "ws2812.h"
+
+
+#include "pico/stdlib.h"
+#include "hardware/pio.h"
+#include "hardware/clocks.h"
+#include "ws2812.pio.h"
+
+#define IS_RGBW true
+#define NUM_PIXELS 150
+
+#ifdef PICO_DEFAULT_WS2812_PIN
+#define WS2812_PIN PICO_DEFAULT_WS2812_PIN
+#else
+// default to pin 2 if the board doesn't have a default WS2812 pin defined
+#define WS2812_PIN 12
+#endif
+int main() {
+ stdio_init_all();
+ gpio_init(11);
+ gpio_set_dir(11, GPIO_OUT);
+ gpio_put(11, 1);
+ PIO pio = pio0;
+ int sm = 0;
+ uint offset = pio_add_program(pio, &ws2812_program);
+ ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);
+ while (true) {
+ printf("Hello, world!\n");
+ sleep_ms(500);
+ set_neopixel_color(0x00337788);
+ sleep_ms(500);
+ printf("see you!\n");
+ set_neopixel_color(0);
+ sleep_ms(500);
+
+ }
+ return 0;
+}
diff --git a/part3.3.pdf b/part3.3.pdf
new file mode 100644
index 0000000..67b0f63
Binary files /dev/null and b/part3.3.pdf differ
diff --git a/part3.4.xlsx b/part3.4.xlsx
new file mode 100644
index 0000000..88200b5
Binary files /dev/null and b/part3.4.xlsx differ
diff --git a/part3.5.pdf b/part3.5.pdf
new file mode 100644
index 0000000..eaf6b57
Binary files /dev/null and b/part3.5.pdf differ
diff --git a/part3.7.pdf b/part3.7.pdf
new file mode 100644
index 0000000..c9a96f6
Binary files /dev/null and b/part3.7.pdf differ
diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake
new file mode 100644
index 0000000..65f8a6f
--- /dev/null
+++ b/pico_sdk_import.cmake
@@ -0,0 +1,73 @@
+# This is a copy of /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})
diff --git a/port3.6 .xlsx b/port3.6 .xlsx
new file mode 100644
index 0000000..545cea2
Binary files /dev/null and b/port3.6 .xlsx differ
diff --git a/ws2812.c b/ws2812.c
new file mode 100644
index 0000000..c8a9254
--- /dev/null
+++ b/ws2812.c
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include
+#include
+
+#include "pico/stdlib.h"
+#include "hardware/pio.h"
+#include "hardware/clocks.h"
+#include "ws2812.pio.h"
+
+#define IS_RGBW true
+#define NUM_PIXELS 150
+
+#ifdef PICO_DEFAULT_WS2812_PIN
+#define WS2812_PIN PICO_DEFAULT_WS2812_PIN
+#else
+// default to pin 2 if the board doesn't have a default WS2812 pin defined
+#define WS2812_PIN 12
+#endif
+
+static inline void put_pixel(uint32_t pixel_grb) {
+ pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
+}
+
+static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
+ return
+ ((uint32_t) (r) << 8) |
+ ((uint32_t) (g) << 16) |
+ (uint32_t) (b);
+}
+
+void pattern_snakes(uint len, uint t) {
+ for (uint i = 0; i < len; ++i) {
+ uint x = (i + (t >> 1)) % 64;
+ if (x < 10)
+ put_pixel(urgb_u32(0xff, 0, 0));
+ else if (x >= 15 && x < 25)
+ put_pixel(urgb_u32(0, 0xff, 0));
+ else if (x >= 30 && x < 40)
+ put_pixel(urgb_u32(0, 0, 0xff));
+ else
+ put_pixel(0);
+ }
+}
+
+void pattern_random(uint len, uint t) {
+ if (t % 8)
+ return;
+ for (int i = 0; i < len; ++i)
+ put_pixel(rand());
+}
+
+void pattern_sparkle(uint len, uint t) {
+ if (t % 8)
+ return;
+ for (int i = 0; i < len; ++i)
+ put_pixel(rand() % 16 ? 0 : 0xffffffff);
+}
+
+void pattern_greys(uint len, uint t) {
+ int max = 100; // let's not draw too much current!
+ t %= max;
+ for (int i = 0; i < len; ++i) {
+ put_pixel(t * 0x10101);
+ if (++t >= max) t = 0;
+ }
+}
+
+void set_neopixel_color(uint32_t color){
+
+ uint8_t r=color>>16;
+ uint8_t g=color>>8;
+ uint8_t b=color;
+ uint32_t result=urgb_u32(r,g,b);
+ put_pixel(result);
+
+}
+
+typedef void (*pattern)(uint len, uint t);
+const struct {
+ pattern pat;
+ const char *name;
+} pattern_table[] = {
+ {pattern_snakes, "Snakes!"},
+ {pattern_random, "Random data"},
+ {pattern_sparkle, "Sparkles"},
+ {pattern_greys, "Greys"},
+};
+
+//int main() {
+ //set_sys_clock_48();
+// stdio_init_all();
+// printf("WS2812 Smoke Test, using pin %d", WS2812_PIN);
+// gpio_init(11);
+// gpio_set_dir(11,GPIO_OUT);
+// gpio_put(11,1);
+// // todo get free sm
+// PIO pio = pio0;
+// int sm = 0;
+// uint offset = pio_add_program(pio, &ws2812_program);
+//
+// ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);
+//
+// int t = 0;
+// while (1) {
+// int pat = rand() % count_of(pattern_table);
+// int dir = (rand() >> 30) & 1 ? 1 : -1;
+// puts(pattern_table[pat].name);
+// puts(dir == 1 ? "(forward)" : "(backward)");
+// for (int i = 0; i < 1000; ++i) {
+// pattern_table[pat].pat(NUM_PIXELS, t);
+// sleep_ms(10);
+// t += dir;
+// }
+// }
+//}
diff --git a/ws2812.h b/ws2812.h
new file mode 100644
index 0000000..43b528a
--- /dev/null
+++ b/ws2812.h
@@ -0,0 +1,4 @@
+#ifndef _WS2812_H
+#define _WS2812_H
+void set_neopixel_color(uint32_t color);
+#endif
diff --git a/ws2812.pio b/ws2812.pio
new file mode 100644
index 0000000..3c31fd6
--- /dev/null
+++ b/ws2812.pio
@@ -0,0 +1,85 @@
+;
+; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+;
+; SPDX-License-Identifier: BSD-3-Clause
+;
+
+.program ws2812
+.side_set 1
+
+.define public T1 2
+.define public T2 5
+.define public T3 3
+
+.lang_opt python sideset_init = pico.PIO.OUT_HIGH
+.lang_opt python out_init = pico.PIO.OUT_HIGH
+.lang_opt python out_shiftdir = 1
+
+.wrap_target
+bitloop:
+ out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls
+ jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse
+do_one:
+ jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse
+do_zero:
+ nop side 0 [T2 - 1] ; Or drive low, for a short pulse
+.wrap
+
+% c-sdk {
+#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);
+}
+%}
+
+.program ws2812_parallel
+
+.define public T1 2
+.define public T2 5
+.define public T3 3
+
+.wrap_target
+ out x, 32
+ mov pins, !null [T1-1]
+ mov pins, x [T2-1]
+ mov pins, null [T3-2]
+.wrap
+
+% c-sdk {
+#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