|
@@ -0,0 +1,103 @@
|
|
|
+/*
|
|
|
+ * testmode.c
|
|
|
+ *
|
|
|
+ * Written & released by Keir Fraser <keir.xen@gmail.com>
|
|
|
+ *
|
|
|
+ * This is free and unencumbered software released into the public domain.
|
|
|
+ * See the file COPYING for more details, or visit <http://unlicense.org>.
|
|
|
+ */
|
|
|
+
|
|
|
+#define CMD_option_bytes 0
|
|
|
+#define CMD_pins 1
|
|
|
+#define CMD_led 2
|
|
|
+
|
|
|
+struct cmd {
|
|
|
+ uint32_t cmd;
|
|
|
+ union {
|
|
|
+ uint8_t pins[64/8];
|
|
|
+ uint32_t x[28/4];
|
|
|
+ } u;
|
|
|
+};
|
|
|
+
|
|
|
+struct rsp {
|
|
|
+ union {
|
|
|
+ uint8_t opt[32];
|
|
|
+ uint8_t pins[64/8];
|
|
|
+ uint32_t x[32/4];
|
|
|
+ } u;
|
|
|
+};
|
|
|
+
|
|
|
+#define TEST_BIT(p,n) (!!((p)[(n)/8] & (1<<((n)&7))))
|
|
|
+#define SET_BIT(p,n) ((p)[(n)/8] |= (1<<((n)&7)))
|
|
|
+
|
|
|
+void testmode_set_pin(unsigned int pin, bool_t level);
|
|
|
+bool_t testmode_get_pin(unsigned int pin);
|
|
|
+void testmode_get_option_bytes(void *buf);
|
|
|
+
|
|
|
+static void set_pins(uint8_t *pins)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ bool_t level;
|
|
|
+
|
|
|
+ for (i = 0; i <= 34; i++) {
|
|
|
+ level = TEST_BIT(pins, i);
|
|
|
+ testmode_set_pin(i, level);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void get_pins(uint8_t *pins)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ bool_t level;
|
|
|
+
|
|
|
+ for (i = 0; i <= 34; i++) {
|
|
|
+ level = testmode_get_pin(i);
|
|
|
+ if (level)
|
|
|
+ SET_BIT(pins, i);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void testmode_process(void)
|
|
|
+{
|
|
|
+ int len = ep_rx_ready(EP_RX);
|
|
|
+ struct cmd cmd;
|
|
|
+ struct rsp rsp;
|
|
|
+
|
|
|
+ if (len < 0)
|
|
|
+ return;
|
|
|
+
|
|
|
+ len = min_t(int, len, 32);
|
|
|
+ usb_read(EP_RX, &cmd, len);
|
|
|
+ if (len < 32)
|
|
|
+ return;
|
|
|
+
|
|
|
+ memset(&rsp, 0, 32);
|
|
|
+
|
|
|
+ switch (cmd.cmd) {
|
|
|
+ case CMD_option_bytes: {
|
|
|
+ testmode_get_option_bytes(rsp.u.opt);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CMD_pins: {
|
|
|
+ set_pins(cmd.u.pins);
|
|
|
+ get_pins(rsp.u.pins);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CMD_led: {
|
|
|
+ act_led(!!cmd.u.pins[0]);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ usb_write(EP_TX, &rsp, 32);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Local variables:
|
|
|
+ * mode: C
|
|
|
+ * c-file-style: "Linux"
|
|
|
+ * c-basic-offset: 4
|
|
|
+ * tab-width: 4
|
|
|
+ * indent-tabs-mode: nil
|
|
|
+ * End:
|
|
|
+ */
|