Browse Source

usb comms working. auto reset not.

Thomas B 2 months ago
parent
commit
6c10b9605f
7 changed files with 146 additions and 2 deletions
  1. 19
    0
      sensor/49-autobrightness.rules
  2. 4
    0
      sensor/Makefile
  3. 7
    0
      sensor/flash.sh
  4. 26
    0
      sensor/include/main.h
  5. 39
    0
      sensor/reset.py
  6. 7
    1
      sensor/src/main.c
  7. 44
    1
      sensor/src/usb.c

+ 19
- 0
sensor/49-autobrightness.rules View File

@@ -0,0 +1,19 @@
1
+# UDEV Rules for AutoBrightness modules.
2
+# This file must be placed at:
3
+#
4
+# /etc/udev/rules.d/49-autobrightness.rules    (preferred location)
5
+#   or
6
+# /lib/udev/rules.d/49-autobrightness.rules    (req'd on some broken systems)
7
+#
8
+# To install, type these commands in a terminal:
9
+#   sudo cp 49-autobrightness.rules /etc/udev/rules.d/49-autobrightness.rules
10
+#   sudo udevadm control --reload-rules
11
+#
12
+# After this file is copied, physically unplug and reconnect the board.
13
+#
14
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", ATTRS{manufacturer}=="xythobuz.de", ATTRS{product}=="AutoBrightness", MODE:="0666"
15
+#
16
+# If you share your linux system with other users, or just don't like the
17
+# idea of write permission for everybody, you can replace MODE:="0666" with
18
+# OWNER:="yourusername" to create the device owned by you, or with
19
+# GROUP:="somegroupname" and mange access using standard unix groups.

+ 4
- 0
sensor/Makefile View File

@@ -451,6 +451,10 @@ program: $(TARGET).hex $(TARGET).eep
451 451
 	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
452 452
 
453 453
 
454
+upload: $(TARGET).hex
455
+	./flash.sh $(TARGET).hex
456
+
457
+
454 458
 # Generate avr-gdb config/init file which does the following:
455 459
 #     define the reset signal, load the target file, connect to target, and set 
456 460
 #     a breakpoint at main().

+ 7
- 0
sensor/flash.sh View File

@@ -0,0 +1,7 @@
1
+#!/bin/bash
2
+
3
+# enter script directory
4
+cd "$(dirname "$0")"
5
+
6
+# upload to bootloader
7
+./micronucleus/commandline/builds/x86_64-linux-gnu/micronucleus $1

+ 26
- 0
sensor/include/main.h View File

@@ -0,0 +1,26 @@
1
+/*
2
+ * main.h
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __MAIN_H__
20
+#define __MAIN_H__
21
+
22
+#include <stdbool.h>
23
+
24
+extern bool keep_feeding;
25
+
26
+#endif // __MAIN_H__

+ 39
- 0
sensor/reset.py View File

@@ -0,0 +1,39 @@
1
+#!/usr/bin/env python
2
+
3
+import usb.core
4
+import usb.util
5
+
6
+CUSTOM_RQ_ECHO = 0 # send back wValue and wIndex, for testing comms reliability
7
+CUSTOM_RQ_RESET = 1 # reset to bootloader
8
+CUSTOM_RQ_GET = 2 # get ldr value
9
+
10
+def is_target_device(dev):
11
+    if dev.manufacturer == "xythobuz.de" and dev.product == "AutoBrightness":
12
+        return True
13
+    return False
14
+
15
+# find our device
16
+dev = usb.core.find(idVendor=0x16c0, idProduct=0x05dc, custom_match=is_target_device)
17
+
18
+# was it found?
19
+if dev is None:
20
+    raise ValueError('Device not found')
21
+
22
+# configure the device
23
+dev.set_configuration()
24
+
25
+# echo
26
+r = dev.ctrl_transfer(usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_IN, CUSTOM_RQ_ECHO, 42, 23, 4)
27
+print("echo", r)
28
+
29
+# reset
30
+r = dev.ctrl_transfer(usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_IN, CUSTOM_RQ_RESET, 0, 0, 1)
31
+print("reset-err", r)
32
+
33
+# value
34
+r = dev.ctrl_transfer(usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_IN, CUSTOM_RQ_GET, 0, 0, 4)
35
+print("value", r)
36
+
37
+# reset ok
38
+r = dev.ctrl_transfer(usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_IN, CUSTOM_RQ_RESET, 42, 23, 1)
39
+print("reset-ok", r)

+ 7
- 1
sensor/src/main.c View File

@@ -23,6 +23,9 @@
23 23
 
24 24
 #include "adc.h"
25 25
 #include "usbdrv.h"
26
+#include "main.h"
27
+
28
+bool keep_feeding = true;
26 29
 
27 30
 int __attribute__((noreturn)) main(void) {
28 31
     wdt_enable(WDTO_1S);
@@ -45,7 +48,10 @@ int __attribute__((noreturn)) main(void) {
45 48
     // enable interrupts and enter main loop for USB polling
46 49
     sei();
47 50
     while (1) {
48
-        wdt_reset();
51
+        if (keep_feeding) {
52
+            wdt_reset();
53
+        }
54
+
49 55
         usbPoll();
50 56
     }
51 57
 }

+ 44
- 1
sensor/src/usb.c View File

@@ -16,9 +16,52 @@
16 16
  * See <http://www.gnu.org/licenses/>.
17 17
  */
18 18
 
19
+#include <avr/wdt.h>
20
+
19 21
 #include "usbdrv.h"
20 22
 #include "osccal.c" // missing usbdrv include, so include here
21 23
 
24
+#include "main.h"
25
+
26
+#define CUSTOM_RQ_ECHO 0 // send back wValue and wIndex, for testing comms reliability
27
+#define CUSTOM_RQ_RESET 1 // reset to bootloader
28
+#define CUSTOM_RQ_GET 2 // get ldr value
29
+
22 30
 usbMsgLen_t usbFunctionSetup(uchar data[8]) {
23
-    return 0;   /* default for not implemented requests: return no data back to host */
31
+    usbRequest_t *rq = (void *)data;
32
+    static uchar dataBuffer[4]; // buffer must stay valid when usbFunctionSetup returns
33
+
34
+    if (rq->bRequest == CUSTOM_RQ_ECHO) {
35
+        // echo -- used for reliability tests
36
+        dataBuffer[0] = rq->wValue.bytes[0];
37
+        dataBuffer[1] = rq->wValue.bytes[1];
38
+        dataBuffer[2] = rq->wIndex.bytes[0];
39
+        dataBuffer[3] = rq->wIndex.bytes[1];
40
+
41
+        usbMsgPtr = dataBuffer; // tell the driver which data to return
42
+        return 4; // tell the driver to send 4 bytes
43
+    } else if (rq->bRequest == CUSTOM_RQ_RESET) {
44
+        // check for proper keys
45
+        if ((rq->wValue.bytes[0] == 42) && (rq->wIndex.bytes[0] == 23)) {
46
+            keep_feeding = false; // watchdog will trigger in one interval
47
+            wdt_reset();
48
+
49
+            dataBuffer[0] = 42; // send confirmation
50
+        } else {
51
+            dataBuffer[0] = 0; // error code
52
+        }
53
+        return 1;
54
+    } else if (rq->bRequest == CUSTOM_RQ_GET) {
55
+        uint32_t ldr_value = 23; // TODO
56
+        dataBuffer[0] = (ldr_value & 0x000000FF) >> 0;
57
+        dataBuffer[1] = (ldr_value & 0x0000FF00) >> 8;
58
+        dataBuffer[2] = (ldr_value & 0x00FF0000) >> 16;
59
+        dataBuffer[3] = (ldr_value & 0xFF000000) >> 24;
60
+
61
+        usbMsgPtr = dataBuffer; // tell the driver which data to return
62
+        return 4; // tell the driver to send 4 bytes
63
+    }
64
+
65
+    // default for not implemented requests: return no data back to host
66
+    return 0;
24 67
 }

Loading…
Cancel
Save