16constexpr uint8_t JOYSTICK_X = 32;
17constexpr uint8_t JOYSTICK_Y = 33;
18constexpr uint8_t JOYSTICK_SW = 0;
21constexpr uint8_t SERVO = 14;
26constexpr uint8_t STEPPER_IN1 = 13;
27constexpr uint8_t STEPPER_IN2 = 12;
28constexpr uint8_t STEPPER_IN3 = 15;
29constexpr uint8_t STEPPER_IN4 = 2;
32constexpr int8_t CAM_PWDN = -1;
33constexpr int8_t CAM_RESET = -1;
34constexpr uint8_t CAM_XCLK = 21;
35constexpr uint8_t CAM_SIOD = 26;
36constexpr uint8_t CAM_SIOC = 27;
37constexpr uint8_t CAM_Y9 = 35;
38constexpr uint8_t CAM_Y8 = 34;
39constexpr uint8_t CAM_Y7 = 39;
40constexpr uint8_t CAM_Y6 = 36;
41constexpr uint8_t CAM_Y5 = 19;
42constexpr uint8_t CAM_Y4 = 18;
43constexpr uint8_t CAM_Y3 = 5;
44constexpr uint8_t CAM_Y2 = 4;
45constexpr uint8_t CAM_VSYNC = 25;
46constexpr uint8_t CAM_HREF = 23;
47constexpr uint8_t CAM_PCLK = 22;
49constexpr uint8_t CAMERA[] = {CAM_XCLK, CAM_SIOD, CAM_SIOC, CAM_Y9, CAM_Y8, CAM_Y7, CAM_Y6,
50 CAM_Y5, CAM_Y4, CAM_Y3, CAM_Y2, CAM_VSYNC, CAM_HREF, CAM_PCLK};
52constexpr uint8_t TURRET[] = {JOYSTICK_X, JOYSTICK_Y, JOYSTICK_SW, SERVO,
53 STEPPER_IN1, STEPPER_IN2, STEPPER_IN3, STEPPER_IN4};
57constexpr unsigned TURRET_COUNT =
sizeof(TURRET) /
sizeof(TURRET[0]);
58constexpr unsigned CAMERA_COUNT =
sizeof(CAMERA) /
sizeof(CAMERA[0]);
61constexpr bool is_reserved(uint8_t p) {
return (p >= 6 && p <= 11) || p == 16 || p == 17; }
63constexpr bool any_reserved(
unsigned i = 0)
65 return i < TURRET_COUNT && (is_reserved(TURRET[i]) || any_reserved(i + 1));
68constexpr bool on_camera(uint8_t p,
unsigned i = 0)
70 return i < CAMERA_COUNT && (CAMERA[i] == p || on_camera(p, i + 1));
73constexpr bool any_on_camera(
unsigned i = 0)
75 return i < TURRET_COUNT && (on_camera(TURRET[i]) || any_on_camera(i + 1));
78constexpr bool any_duplicate(
unsigned i = 0,
unsigned j = 1)
80 return i < TURRET_COUNT &&
81 (j < TURRET_COUNT ? (TURRET[i] == TURRET[j] || any_duplicate(i, j + 1)) : any_duplicate(i + 1, i + 2));
84constexpr bool is_adc1(uint8_t p) {
return p >= 32 && p <= 39; }
87static_assert(!check::any_reserved(),
"A turret pin uses GPIO 6-11 (flash) or 16/17 (PSRAM)");
88static_assert(!check::any_on_camera(),
"A turret pin collides with the camera bus");
89static_assert(!check::any_duplicate(),
"Two turret signals share a GPIO");
90static_assert(check::is_adc1(JOYSTICK_X) && check::is_adc1(JOYSTICK_Y),
"Joystick axes must be on ADC1 (GPIO 32-39)");
91static_assert(STEPPER_IN1 != 0 && STEPPER_IN2 != 0 && STEPPER_IN3 != 0 && STEPPER_IN4 != 0,
92 "The ULN2003 would hold GPIO 0 low at boot and force flash mode");