#include <freq.h>

#include <zephyr/dt-bindings/i2c/i2c.h>
#include <zephyr/dt-bindings/pwm/pwm.h>
#include <zephyr/dt-bindings/input/input-event-codes.h>

#include "servo2350-pinctrl.dtsi"

/ {
	chosen {
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,console = &cdc_acm_uart0;
		zephyr,shell-uart = &cdc_acm_uart0;
		zephyr,code-partition = &code_partition;
	};

	zephyr,user {
		io-channels = 	<&adc 0>,
						<&adc 1>,
						<&adc 2>;
	};

	leds {
		compatible = "gpio-leds";

		led0: led_0 {
			gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
			label = "LED0";
		};
		led1: led_1 {
			gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
			label = "LED1";
		};
	};

	imu_int1_pin {
		compatible = "gpio-keys";

		imu_int1: imu_int1 {
			gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
			label = "IMU_INT1";
		};

		imu_int2: imu_int2 {
			gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
			label = "IMU_INT2";
		};
	};

	digital_inputs {
		compatible = "gpio-keys";

		digital1: digital_1 {
			gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
			label = "DIGITAL_1";
		};
		digital2: digital_2 {
			gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
			label = "DIGITAL_2";
		};
		digital3: digital_3 {
			gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
			label = "DIGITAL_3";
		};
		digital4: digital_4 {
			gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
			label = "DIGITAL_4";
		};
		digital5: digital_5 {
			gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
			label = "DIGITAL_5";
		};
		digital6: digital_6 {
			gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
			label = "DIGITAL_6";
		};
	};

	digital_outputs {
		compatible = "gpio-leds";

		leg0_enable: leg0_enable {
			gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
			label = "LEG0_ENABLE";
		};
		leg1_enable: leg1_enable {
			gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
			label = "LEG1_ENABLE";
		};
		leg2_enable: leg2_enable {
			gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
			label = "LEG2_ENABLE";
		};
		leg3_enable: leg3_enable {
			gpios = <&gpio0_hi 11 GPIO_ACTIVE_HIGH>;
			label = "LEG3_ENABLE";
		};
		leg4_enable: leg4_enable {
			gpios = <&gpio0_hi 12 GPIO_ACTIVE_HIGH>;
			label = "LEG4_ENABLE";
		};
		leg5_enable: leg5_enable {
			gpios = <&gpio0_hi 13 GPIO_ACTIVE_HIGH>;
			label = "LEG5_ENABLE";
		};
	};

	pwm_servos {
		compatible = "pwm-leds";

		servo1: servo_1 {
			pwms = <&pwm 0 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_1";
		};
		servo2: servo_2 {
			pwms = <&pwm 1 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_2";
		};
		servo3: servo_3 {
			pwms = <&pwm 2 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_3";
		};
		servo4: servo_4 {
			pwms = <&pwm 3 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_4";
		};
		servo5: servo_5 {
			pwms = <&pwm 4 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_5";
		};
		servo6: servo_6 {
			pwms = <&pwm 5 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_6";
		};
		servo7: servo_7 {
			pwms = <&pwm 6 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_7";
		};
		servo8: servo_8 {
			pwms = <&pwm 7 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_8";
		};
		servo9: servo_9 {
			pwms = <&pwm 8 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_9";
		};
		servo10: servo_10 {
			pwms = <&pwm 9 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_10";
		};
		servo11: servo_11 {
			pwms = <&pwm 10 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_11";
		};
		servo12: servo_12 {
			pwms = <&pwm 11 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_12";
		};
		servo13: servo_13 {
			pwms = <&pwm 12 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_13";
		};
		servo14: servo_14 {
			pwms = <&pwm 13 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_14";
		};
		servo15: servo_15 {
			pwms = <&pwm 14 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_15";
		};
		servo16: servo_16 {
			pwms = <&pwm 15 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_16";
		};
		servo17: servo_17 {
			pwms = <&pwm 16 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_17";
		};
		servo18: servo_18 {
			pwms = <&pwm 17 PWM_USEC(20000) PWM_POLARITY_NORMAL>;
			label = "SERVO_18";
		};
	};

	mux: mux {
		compatible = "cd74hc4067";
		status = "okay";
		select-gpios =  <&gpio0_hi 2 GPIO_ACTIVE_HIGH>,
					    <&gpio0_hi 3 GPIO_ACTIVE_HIGH>,
					    <&gpio0_hi 6 GPIO_ACTIVE_HIGH>,
					    <&gpio0_hi 7 GPIO_ACTIVE_HIGH>;
	};

	aliases {
		watchdog0 = &wdt0;
		led0 = &led0;
		led1 = &led1;
		imu = &imu;
		imu-int1 = &imu_int1;
		imu-int2 = &imu_int2;
		digital1 = &digital1;
		digital2 = &digital2;
		digital3 = &digital3;
		digital4 = &digital4;
		digital5 = &digital5;
		digital6 = &digital6;
		leg0-enable = &leg0_enable;
		leg1-enable = &leg1_enable;
		leg2-enable = &leg2_enable;
		leg3-enable = &leg3_enable;
		leg4-enable = &leg4_enable;
		leg5-enable = &leg5_enable;
		servo1 = &servo1;
		servo2 = &servo2;
		servo3 = &servo3;
		servo4 = &servo4;
		servo5 = &servo5;
		servo6 = &servo6;
		servo7 = &servo7;
		servo8 = &servo8;
		servo9 = &servo9;
		servo10 = &servo10;
		servo11 = &servo11;
		servo12 = &servo12;
		servo13 = &servo13;
		servo14 = &servo14;
		servo15 = &servo15;
		servo16 = &servo16;
		servo17 = &servo17;
		servo18 = &servo18;
		mux = &mux;
	};
};

&flash0 {
	/* W25Q16JVUXIQ_TR: 16M-bit (2MB) NOR Flash */
	reg = <0x10000000 DT_SIZE_M(2)>;

	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		/* Code partition: 256KB for application code (starts at beginning of flash) */
		code_partition: partition@0 {
			label = "code";
			reg = <0x00000000 DT_SIZE_K(256)>;
			read-only;
		};

		/* Settings partition: 64KB for settings data */
		settings_partition: partition@40000 {
			label = "settings";
			reg = <0x00040000 DT_SIZE_K(64)>;
		};

		/* Data partition: 1728KB for data storage (largest partition) */
		data_partition: partition@50000 {
			label = "data";
			reg = <0x00050000 DT_SIZE_K(1728)>;
		};
	};
};

zephyr_udc0: &usbd {
	status = "okay";
	cdc_acm_uart0: cdc_acm_uart0 {
		compatible = "zephyr,cdc-acm-uart";
		label = "USB_CDC";
	};
};

gpio0_lo: &gpio0 {
	status = "okay";
};

&gpio0_hi {
	status = "okay";

};

&i2c0 {
	pinctrl-0 = <&i2c0_default>;
	pinctrl-names = "default";
	status = "okay";
	clock-frequency = <I2C_BITRATE_FAST>;

	imu: icm45686@68 {
		compatible = "invensense,icm42688";
		reg = <0x68>;
		status = "okay";

		int1-gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
		int2-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;

		accel-pwr-mode = <3>;
		accel-ord = <9>;
		accel-fs = <16>;
		accel-lpf = <0>;

		gyro-pwr-mode = <0>; /* turn off */
		gyro-ord = <9>;
		gyro-fs = <2000>;
	};
};

&spi1 {
	clock-frequency = <DT_FREQ_M(8)>;
	pinctrl-0 = <&spi1_default>;
	pinctrl-names = "default";
	status = "disabled";
};

&adc {
	pinctrl-0 = <&adc_default>;
	pinctrl-names = "default";
	status = "okay";
	#address-cells = <1>;
	#size-cells = <0>;

	adc0: channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <12>;
	};

	adc1: channel@1 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <12>;
	};

	adc2: channel@2 {
		reg = <2>;
		zephyr,gain = "ADC_GAIN_1";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,resolution = <12>;
	};
};

&pwm {
	status = "okay";
	pinctrl-0 = <&pwm_default>;
	pinctrl-names = "default";
	divider-int-0 = <64>;
};

&timer0 {
	status = "okay";
};
