diff --git a/.idea/misc.xml b/.idea/misc.xml
index abc895b8541ef12cbe7973054c9c3d7ccce71596..58ad7c3f0025b897bd7f5c1b337a3421a6a0395b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -2,7 +2,7 @@
 <project version="4">
   <component name="BackendCodeEditorMiscSettings">
     <option name="/Default/Housekeeping/GlobalSettingsUpgraded/IsUpgraded/@EntryValue" value="true" type="bool" />
-    <option name="/Default/Environment/Hierarchy/GeneratedFilesCacheKey/Timestamp/@EntryValue" value="5" type="long" />
+    <option name="/Default/Environment/Hierarchy/GeneratedFilesCacheKey/Timestamp/@EntryValue" value="6" type="long" />
     <option name="/Default/Housekeeping/OptionsDialog/SelectedPageId/@EntryValue" value="CppIncludesOrderOptions" type="string" />
   </component>
   <component name="CMakePythonSetting">
diff --git a/src/A2/CMakeLists.txt b/src/A2/CMakeLists.txt
index a98fad3b1285edae23cbebd0fe1a3c1ac12eb642..c645c5f3e41e38f03f84613a040e5a53cb6b7f94 100644
--- a/src/A2/CMakeLists.txt
+++ b/src/A2/CMakeLists.txt
@@ -1,5 +1,5 @@
 # Add the executable target
-add_executable(A2 src/A2/main.c)
+add_executable(A2 src/A2/main.c src/A2/i2c.c src/A2/encoder.c src/A2/pwm.c src/A2/smart_knob.c)
 # Modify the below lines to enable/disable output over UART/USB
 pico_enable_stdio_uart(A2 0)
 pico_enable_stdio_usb(A2 1)
diff --git a/src/A2/encoder.c b/src/A2/encoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..ecac7d041f20f9b73740587a8e028cefd1f09853
--- /dev/null
+++ b/src/A2/encoder.c
@@ -0,0 +1,72 @@
+#include "encoder.h"
+#include "i2c.h"
+
+/** Initializes the encoder by setting the slow filter mode.
+ * This function should not call init_i2c(...), the bus has to be initialized before using this function.
+ *  @param slow_filter [2 = 2x, 4 = 4x, 8 = 8x, 16 = 16x] slow filter mode. Ensure that a valid value is provided, otherwise use 2x.
+ */
+void init_encoder(int slow_filter)
+{
+	// TODO student:
+	//  - check if a valid slow filter mode is provided, otherwise use 2x
+	//  - initialize the encoder by setting the slow filter mode
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Reads the raw 12-bit rotation value of the encoder from the RAW ANGLE register.
+ *  @return the raw rotation value of the encoder
+ */
+int read_encoder_raw()
+{
+	// TODO student:
+	//  - read the raw 12-bit rotation value of the encoder from the RAW ANGLE register
+	//  - return the raw rotation value of the encoder
+	//  ======================================================================
+
+
+
+
+
+	return 0;
+	// TODO end ==============================================================
+}
+
+/** Sets the zero value of the encoder to the given value.
+ *  @param zero_value the zero value to set
+ */
+void set_encoder_zero(int zero_value)
+{
+	// TODO student:
+	//  - set the zero value of the encoder to the given value
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Reads the zero-corrected rotation value of the encoder in degrees from the ANGLE register.
+ *  @return the zero-corrected rotation value of the encoder
+ */
+float read_encoder()
+{
+	// TODO student:
+	//  - read the zero-corrected rotation value of the encoder from the ANGLE register
+	//  - convert the value to degrees
+	//  - return the zero-corrected rotation value of the encoder
+	//  ======================================================================
+	
+
+
+
+
+	// TODO end ==============================================================
+}
\ No newline at end of file
diff --git a/src/A2/encoder.h b/src/A2/encoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..255595c31471cc67fb70920d6f3a221607ed7b4a
--- /dev/null
+++ b/src/A2/encoder.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#define ENCODER_ADDRESS 0x36
+
+/** Initializes the encoder by setting the slow filter mode.
+ * This function should not call init_i2c(...), the bus has to be initialized before using this function.
+ *  @param slow_filter [2 = 2x, 4 = 4x, 8 = 8x, 16 = 16x] slow filter mode. Ensure that a valid value is provided, otherwise use 2x.
+ */
+void init_encoder(int slow_filter);
+
+/** Reads the raw 12-bit rotation value of the encoder from the RAW ANGLE register.
+ *  @return the raw rotation value of the encoder
+ */
+int read_encoder_raw();
+
+/** Sets the zero value of the encoder to the given value.
+ *  @param zero_value the zero value to set
+ */
+void set_encoder_zero(int zero_value);
+
+/** Reads the zero-corrected rotation value of the encoder from the ANGLE register.
+ *  @return the zero-corrected rotation value in degrees
+ */
+float read_encoder();
\ No newline at end of file
diff --git a/src/A2/i2c.c b/src/A2/i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..077d7ba797bfaaf93130b4fc5851e9ce7865b855
--- /dev/null
+++ b/src/A2/i2c.c
@@ -0,0 +1,124 @@
+#include "i2c.h"
+#include <hardware/gpio.h>
+
+/** Initializes the I2C-0 interface and configures the pins for SDA and SCL.
+ *  @param sda_pin id of the gpio pin for SDA (you can assume that a valid pin is given)
+ *  @param scl_pin id of the gpio pin for SCL (you can assume that a valid pin is given)
+ *  @param baudrate the I2C baudrate in Hz
+ */
+void init_i2c(int sda_pin, int scl_pin, int baudrate)
+{
+	// TODO student:
+	//  - initialize the SDA and SCL pins for I2C communication
+	//  - initialize the I2C-0 interface with the given baudrate
+	//  ======================================================================
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Checks if the device with the given I2C address is connected to the bus.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @return 1 if the device is connected, 0 otherwise
+ */
+int check_i2c_device(unsigned char address)
+{
+	// TODO student:
+	//  - check if a valid address is provided, otherwise return -1
+	//  - check if the device with the given address is connected to the I2C bus
+	//  - return 1 if the device is connected, 0 otherwise
+	//  ======================================================================
+
+
+
+
+
+	return -1;
+	// TODO end ==============================================================
+}
+
+/** Writes a byte into the specified register of the I2C device.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to write to
+ *  @param data the byte to write
+ *  @return 0 if the write was successful, -1 otherwise
+ */
+int write_i2c_register_byte(unsigned char address, unsigned char reg, unsigned char data)
+{
+	// TODO student:
+	//  - check if a valid address is provided, otherwise return -1
+	//  - write the given data into the specified register of the I2C device
+	//  ======================================================================
+
+
+
+
+
+	return -1;
+	// TODO end ==============================================================
+}
+
+/** Writes a word (two bytes) into the specified register of the I2C device. The first byte written is the high byte, the second byte written is the low byte.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to write to
+ *  @param data the word to write
+ *  @return 0 if the write was successful, -1 otherwise
+ */
+int write_i2c_register_word(unsigned char address, unsigned char reg, unsigned int data)
+{
+	// TODO student:
+	//  - check if a valid address is provided, otherwise return -1
+	//  - write the given data into the specified register of the I2C device
+	//  ======================================================================
+
+
+
+
+
+	return -1;
+	// TODO end ==============================================================
+}
+
+/** Reads a byte from the specified register of the I2C device.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to read from
+ *  @return the byte read from the bus
+ */
+int read_i2c_register_byte(unsigned char address, unsigned char reg)
+{
+	// TODO student:
+	//  - check if a valid address is provide, otherwise return -1
+	//  - read a byte from the specified register of the I2C device
+	//  - return the byte read from the bus
+	//  ======================================================================
+
+
+
+
+
+	return -1;
+	// TODO end ==============================================================
+}
+
+
+/** Reads a word (two bytes) from the specified register of the I2C device. The first byte read is the high byte, the second byte read is the low byte.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to read from
+ *  @return the word read from the bus
+ */
+int read_i2c_register_word(unsigned char address, unsigned char reg)
+{
+	// TODO student:
+	//  - check if a valid address is provided, otherwise return -1
+	//  - read a word from the specified register of the I2C device
+	//  - return the word read from the bus
+	//  ======================================================================
+
+
+
+
+
+	return -1;
+	// TODO end ==============================================================
+}
diff --git a/src/A2/i2c.h b/src/A2/i2c.h
new file mode 100644
index 0000000000000000000000000000000000000000..00f20b7603efa44b6925d554acd75498f9a05c3c
--- /dev/null
+++ b/src/A2/i2c.h
@@ -0,0 +1,51 @@
+#pragma once
+#include <hardware/i2c.h>
+
+#define I2C_INTERFACE &i2c0_inst
+#define I2C_SDA_PIN 16
+#define I2C_SCL_PIN 17
+
+#define I2C_BAUDRATE 100000 // feel free to change this value
+
+/** Initializes the I2C-0 interface and configures the pins for SDA and SCL.
+ *  @param sda_pin id of the gpio pin for SDA (you can assume that a valid pin is given)
+ *  @param scl_pin id of the gpio pin for SCL (you can assume that a valid pin is given)
+ *  @param baudrate the I2C baudrate in Hz
+ */
+void init_i2c(int sda_pin, int scl_pin, int baudrate);
+
+/** Checks if the device with the given I2C address is connected to the bus.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @return 1 if the device is connected, 0 otherwise
+ */
+int check_i2c_device(unsigned char address);
+
+/** Writes a byte into the specified register of the I2C device.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to write to
+ *  @param data the byte to write
+ *  @return 0 if the write was successful, -1 otherwise
+ */
+int write_i2c_register_byte(unsigned char address, unsigned char reg, unsigned char data);
+
+/** Writes a word (two bytes) into the specified register of the I2C device. The first byte written is the high byte, the second byte written is the low byte.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to write to
+ *  @param data the word to write
+ *  @return 0 if the write was successful, -1 otherwise
+ */
+int write_i2c_register_word(unsigned char address, unsigned char reg, unsigned int data);
+
+/** Reads a byte from the specified register of the I2C device.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to read from
+ *  @return the byte read from the bus
+ */
+int read_i2c_register_byte(unsigned char address, unsigned char reg);
+
+/** Reads a word (two bytes) from the specified register of the I2C device. The first byte read is the high byte, the second byte read is the low byte.
+ *  @param address the I2C address of the device, ensure that it is a valid address
+ *  @param reg address of the register to read from
+ *  @return the word read from the bus
+ */
+int read_i2c_register_word(unsigned char address, unsigned char reg);
\ No newline at end of file
diff --git a/src/A2/main.c b/src/A2/main.c
index 3c0a592d84be63b3137d5e63fb14a321d0aa1533..7b0ea558faf74ae436634fbfe43c5cf18cc40ccf 100644
--- a/src/A2/main.c
+++ b/src/A2/main.c
@@ -1,9 +1,8 @@
-
+#include "smart_knob.h"
 
 // You can modify this file for local testing, but it will be overridden by the testsystem
 
 int main()
 {
-
-	while (1);
+	smart_knob_logic();
 }
diff --git a/src/A2/pwm.c b/src/A2/pwm.c
new file mode 100644
index 0000000000000000000000000000000000000000..dde662c2fe32fe3f3774147d3e360fce03f76544
--- /dev/null
+++ b/src/A2/pwm.c
@@ -0,0 +1,157 @@
+#include "pwm.h"
+#include <hardware/gpio.h>
+#include <hardware/clocks.h>
+#include <hardware/pwm.h>
+
+// TODO student:
+//  - use these global variables to store the pwm wrap values for the motor and the LED
+//    and use it for duty cycle calculations
+int motor_pwm_wrap;
+int led_pwm_wrap;
+
+/** Initializes all three motor-channel pins for PWM usage and enables the pwm output for all three simultaneously. The duty cycle of the pwm signals should be set to 0. The wrap value should be stored in the motor_pwm_wrap variable.
+ *  @param frequency the pwm frequency in Hz
+ */
+void init_pwm_channels(int frequency)
+{
+	// TODO student:
+	//  - initialize the three motor-channel pins for PWM usage
+	//  - configure the pwm frequency to the given value
+	//  - store the wrap value in the motor_pwm_frequency variable
+	//  - enable the pwm output for all three channels simultaneously
+	//  - set the duty cycle of the pwm signals to 0
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Initializes the LED pin for PWM usage and enables the pwm output. The duty cycle of the pwm signal should be set to 0. The wrap value should be stored in the led_pwm_wrap variable.
+ *  @param frequency the pwm frequency in Hz
+ */
+void init_led_pwm(int frequency)
+{
+	// TODO student:
+	//  - initialize the LED pin for PWM usage
+	//  - configure the pwm frequency to the given value
+	//  - store the wrap value in the led_pwm_frequency variable
+	//  - enable the pwm output for the LED pin
+	//  - set the duty cycle of the pwm signal to 0
+	//  ======================================================================
+
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Sets the duty cycle of the LED pin to the given value.
+ *  @param duty_cycle the duty cycle to set. Ensure that a valid value between 0 and 100 is provided.
+ */
+void set_led_pwm_duty_cycle(int duty_cycle)
+{
+	// TODO student:
+	//  - ensure that a valid value between 0 and 100 is provided, otherwise return
+	//  - set the duty cycle of the LED pin to the given value
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Initializes the enable pin for the motor driver as an output (no PWM) and sets the pin to low.
+ */
+void init_enable_pin()
+{
+	// TODO student:
+	//  - initialize the enable pin for the motor driver as an output (no PWM)
+	//  - set the pin to low
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Sets the level of the enable pin to the given value.
+ *  @param value the value to set the enable pin to. 1 for high, 0 for low.
+ */
+void set_enable_pin(int value)
+{
+	// TODO student:
+	//  - set the level of the enable pin to the given value (0 for low, high otherwise)
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Sets the duty cycle of the pwm signal for the given channel.
+ *  @param channel the channel to set the duty cycle for. 1 for channel 1, 2 for channel 2, 3 for channel 3.
+ *  @param duty_cycle the duty cycle to set. Ensure that a valid value between 0 and MAX_DUTY_CYCLE is provided.
+ */
+void set_pwm_duty_cycle(int channel, int duty_cycle)
+{
+	// TODO student:
+	//  - ensure that a valid duty cycle between 0 and MAX_DUTY_CYCLE is provided, otherwise return
+	//  - set the duty cycle of the pwm signal for the given channel to the given value
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Sets the duty cycle of all three pins so that a 3-phase signal is generated with the given angle and amplitude.
+ *  @param angle the angle of the 3-phase signal in degrees. Ensure that a value between 0 and 360 is provided.
+ *  @param amplitude the amplitude of the 3-phase signal. Ensure that a value between 0.0 and 1.0 is provided. 1.0 corresponds to MAX_DUTY_CYCLE.
+ */
+void set_3phase_pwm(float angle, float amplitude)
+{
+	// TODO student:
+	//  - ensure that a valid angle between 0 and 360 is provided for the angle, otherwise return
+	//  - ensure that a valid amplitude between 0.0 and 1.0 is provided for the amplitude, otherwise return
+	//  - set the duty cycle of all three pins so that a 3-phase signal is generated with the given angle and amplitude
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
+
+/** Sets the angle of the motor to the given value by rotating the three phases according to the seven pole pairs inside the motor.
+ * @param angle the angle of the motor in degrees. Ensure that a value between 0 and 360 is provided, otherwise add/subtract 360 to the angle to ensure it is in the valid range
+ * @param amplitude the maximum amplitude of the PWM signal. Ensure that a value between 0.0 and 1.0 is provided. 1.0 corresponds to MAX_DUTY_CYCLE.
+ */
+void set_motor_angle(float angle, float amplitude)
+{
+	// TODO student:
+	//  - ensure that a valid angle between 0 and 360 is provided for the angle, otherwise add/subtract 360 to the angle to ensure it is in the valid range
+	//  - ensure that a valid amplitude between 0.0 and 1.0 is provided for the amplitude, otherwise return
+	//  - set the PWM angle and amplitude to control the motor rotation by setting the right duty cycles for the three phases
+	//  Hint: the motor has seven coils, which are rotated by the three-phase signal.
+	//  ======================================================================
+
+
+
+
+
+	// TODO end ==============================================================
+}
\ No newline at end of file
diff --git a/src/A2/pwm.h b/src/A2/pwm.h
new file mode 100644
index 0000000000000000000000000000000000000000..49db06c0979e879b7b8be3e13aec105483615d75
--- /dev/null
+++ b/src/A2/pwm.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#define CHANNEL1_PIN 18
+#define CHANNEL2_PIN 19
+#define CHANNEL3_PIN 20
+
+#define ENABLE_PIN 21
+
+#define MAX_DUTY_CYCLE 30
+
+#define DEFAULT_PWM_FREQUENCY 20000
+
+/** Initializes all three motor-channel pins for PWM usage and enables the pwm output for all three simultaneously. The duty cycle of the pwm signals should be set to 0. The wrap value should be stored in the motor_pwm_wrap variable.
+ *  @param frequency the pwm frequency in Hz
+ */
+void init_pwm_channels(int frequency);
+
+/** Initializes the LED pin for PWM usage and enables the pwm output. The duty cycle of the pwm signal should be set to 0. The wrap value should be stored in the led_pwm_wrap variable.
+ *  @param frequency the pwm frequency in Hz
+ */
+void init_led_pwm(int frequency);
+
+/** Sets the duty cycle of the LED pin to the given value.
+ *  @param duty_cycle the duty cycle to set. Ensure that a valid value between 0 and 100 is provided.
+ */
+void set_led_pwm_duty_cycle(int duty_cycle);
+
+/** Initializes the enable pin for the motor driver as an output (no PWM) and sets the pin to low.
+ */
+void init_enable_pin();
+
+/** Sets the level of the enable pin to the given value.
+ *  @param value the value to set the enable pin to. 1 for high, 0 for low.
+ */
+void set_enable_pin(int value);
+
+/** Sets the duty cycle of the pwm signal for the given channel.
+ *  @param channel the channel to set the duty cycle for. 1 for channel 1, 2 for channel 2, 3 for channel 3.
+ *  @param duty_cycle the duty cycle to set. Ensure that a valid value between 0 and MAX_DUTY_CYCLE is provided.
+ */
+void set_pwm_duty_cycle(int channel, int duty_cycle);
+
+/** Sets the duty cycle of all three pins so that a 3-phase signal is generated with the given angle and amplitude.
+ *  @param angle the angle of the 3-phase signal in degrees. Ensure that a value between 0 and 360 is provided.
+ *  @param amplitude the amplitude of the 3-phase signal. Ensure that a value between 0.0 and 1.0 is provided. 1.0 corresponds to MAX_DUTY_CYCLE.
+ */
+void set_3phase_pwm(float angle, float amplitude);
+
+/** Sets the angle of the motor to the given value by rotating the three phases according to the seven pole pairs inside the motor.
+ * @param angle the angle of the motor in degrees. Ensure that a value between 0 and 360 is provided, otherwise add/subtract 360 to the angle to ensure it is in the valid range
+ * @param amplitude the maximum amplitude of the PWM signal. Ensure that a value between 0.0 and 1.0 is provided. 1.0 corresponds to MAX_DUTY_CYCLE.
+ */
+void set_motor_angle(float angle, float amplitude);
+
diff --git a/src/A2/smart_knob.c b/src/A2/smart_knob.c
new file mode 100644
index 0000000000000000000000000000000000000000..3baf9f780a0451371dc3c0544f59d70fb84081b8
--- /dev/null
+++ b/src/A2/smart_knob.c
@@ -0,0 +1,29 @@
+#include "smart_knob.h"
+#include "encoder.h"
+#include "i2c.h"
+#include "pwm.h"
+
+/** Implement your logic for the smart knob here. This function should never return. */
+void smart_knob_logic()
+{
+	//TODO student:
+	// - implement the smart knob functionality as described in the assignment
+	// - do not forget to initialize the I2C, PWM and encoder interfaces
+	// - use your functions defined in encoder.c and pwm.c
+	// - use the define DEFAULT_PWM_FREQUENCY for the pwm frequency
+	// ======================================================================
+
+
+
+
+
+	while (1) // infinite loop to prevent returning
+	{
+
+
+
+
+
+	}
+	//TODO end ==============================================================
+}
\ No newline at end of file
diff --git a/src/A2/smart_knob.h b/src/A2/smart_knob.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c9090e93c83040ee964a83e2788f66ee3a11cac
--- /dev/null
+++ b/src/A2/smart_knob.h
@@ -0,0 +1,4 @@
+#pragma once
+
+/** Implement your logic for the smart knob here. This function should never return. */
+void smart_knob_logic();
\ No newline at end of file