Browse Source

add readme and volume label to fat. unplug disk on eject by host. support visualizing binary frame dump file.

Thomas Buck 1 year ago
parent
commit
68bf4eccac
3 changed files with 91 additions and 14 deletions
  1. 40
    0
      firmware/src/fat_disk.c
  2. 37
    8
      firmware/src/usb_msc.c
  3. 14
    6
      firmware/util/visualize_frame.py

+ 40
- 0
firmware/src/fat_disk.c View File

@@ -4,6 +4,7 @@
4 4
 
5 5
 #include <string.h>
6 6
 #include <stdlib.h>
7
+#include <stdio.h>
7 8
 
8 9
 #include "pico/stdlib.h"
9 10
 #include "ff.h"
@@ -11,6 +12,7 @@
11 12
 
12 13
 #include "config.h"
13 14
 #include "log.h"
15
+#include "debug.h"
14 16
 #include "fat_disk.h"
15 17
 
16 18
 static uint8_t disk[DISK_BLOCK_COUNT * DISK_BLOCK_SIZE];
@@ -22,6 +24,44 @@ void fat_disk_init(void) {
22 24
         debug("error: f_mkfs returned %d", res);
23 25
         return;
24 26
     }
27
+
28
+    if (debug_msc_mount() != 0) {
29
+        debug("error mounting disk");
30
+        return;
31
+    }
32
+
33
+    // maximum length: 11 bytes
34
+    f_setlabel("DEBUG DISK");
35
+
36
+    FIL file;
37
+    res = f_open(&file, "README.md", FA_CREATE_ALWAYS | FA_WRITE);
38
+    if (res != FR_OK) {
39
+        debug("error: f_open returned %d", res);
40
+    } else {
41
+        char readme[1024];
42
+        size_t pos = 0;
43
+        pos += snprintf(readme + pos, 1024 - pos, "# Trackball\r\n");
44
+        pos += snprintf(readme + pos, 1024 - pos, "\r\n");
45
+        pos += snprintf(readme + pos, 1024 - pos, "Project by Thomas Buck <thomas@xythobuz.de>\r\n");
46
+        pos += snprintf(readme + pos, 1024 - pos, "Licensed under GPLv3.\r\n");
47
+        pos += snprintf(readme + pos, 1024 - pos, "Source at https://git.xythobuz.de/thomas/Trackball\r\n");
48
+
49
+        size_t len = strlen(readme);
50
+        UINT bw;
51
+        res = f_write(&file, readme, len, &bw);
52
+        if ((res != FR_OK) || (bw != len)) {
53
+            debug("error: f_write returned %d", res);
54
+        }
55
+
56
+        res = f_close(&file);
57
+        if (res != FR_OK) {
58
+            debug("error: f_close returned %d", res);
59
+        }
60
+    }
61
+
62
+    if (debug_msc_unmount() != 0) {
63
+        debug("error unmounting disk");
64
+    }
25 65
 }
26 66
 
27 67
 uint8_t *fat_disk_get_sector(uint32_t sector) {

+ 37
- 8
firmware/src/usb_msc.c View File

@@ -1,6 +1,8 @@
1 1
 /* 
2
- * The MIT License (MIT)
2
+ * Extended from TinyUSB example code.
3
+ * Copyright (c) 2022 Thomas Buck (thomas@xythobuz.de)
3 4
  *
5
+ * The MIT License (MIT)
4 6
  * Copyright (c) 2019 Ha Thach (tinyusb.org)
5 7
  *
6 8
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,7 +22,6 @@
20 22
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 24
  * THE SOFTWARE.
23
- *
24 25
  */
25 26
 
26 27
 #include "bsp/board.h"
@@ -63,13 +64,12 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8],
63 64
 // Invoked when received Test Unit Ready command.
64 65
 // return true allowing host to read/write this LUN e.g SD card inserted
65 66
 bool tud_msc_test_unit_ready_cb(uint8_t lun) {
66
-    if (ejected || !medium_available) {
67
+    if (!medium_available) {
67 68
         // Additional Sense 3A-00 is NOT_FOUND
68 69
         tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
69
-        return false;
70 70
     }
71 71
 
72
-    return true;
72
+    return medium_available;
73 73
 }
74 74
 
75 75
 // Invoked when received SCSI_CMD_READ_CAPACITY_10 and
@@ -78,8 +78,13 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) {
78 78
 void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
79 79
     (void) lun;
80 80
 
81
-    *block_count = DISK_BLOCK_COUNT;
82
-    *block_size  = DISK_BLOCK_SIZE;
81
+    if (!medium_available) {
82
+        *block_count = 0;
83
+        *block_size = 0;
84
+    } else {
85
+        *block_count = DISK_BLOCK_COUNT;
86
+        *block_size  = DISK_BLOCK_SIZE;
87
+    }
83 88
 }
84 89
 
85 90
 // Invoked when received Start Stop Unit command
@@ -96,7 +101,9 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition,
96 101
     } else {
97 102
         // unload disk storage
98 103
         debug("unload disk storage %d", load_eject);
99
-        ejected = true;
104
+        if (load_eject) {
105
+            medium_available = false;
106
+        }
100 107
     }
101 108
 
102 109
     return true;
@@ -158,6 +165,28 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16],
158 165
     bool in_xfer = true;
159 166
 
160 167
     switch (scsi_cmd[0]) {
168
+    case 0x1E:
169
+        // Prevent/Allow Medium Removal
170
+        if (scsi_cmd[4] & 0x01) {
171
+            // Prevent medium removal
172
+            if (!medium_available) {
173
+                debug("Host wants to lock non-existing medium. Not supported.");
174
+                resplen = -1;
175
+            } else {
176
+                debug("Host wants to lock medium.");
177
+            }
178
+        } else {
179
+            // Allow medium removal
180
+            if (medium_available) {
181
+                debug("Host ejected medium. Unplugging disk.");
182
+                medium_available = false;
183
+            } else {
184
+                debug("host ejected non-existing medium. Not supported.");
185
+                resplen = -1;
186
+            }
187
+        }
188
+        break;
189
+
161 190
     default:
162 191
         // Set Sense = Invalid Command Operation
163 192
         tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);

+ 14
- 6
firmware/util/visualize_frame.py View File

@@ -4,6 +4,7 @@ import matplotlib.pyplot as plt
4 4
 import numpy as np
5 5
 import sys
6 6
 import math
7
+import os
7 8
 
8 9
 if len(sys.argv) < 2:
9 10
     print("Usage:")
@@ -20,12 +21,19 @@ for n in range(0, len(sys.argv) - 1):
20 21
     print("reading " + sys.argv[n + 1])
21 22
 
22 23
     frame = []
23
-    with open(sys.argv[n + 1]) as f:
24
-        lines = f.readlines()
25
-        for line in lines:
26
-            nums = line.split()
27
-            for r in nums:
28
-                frame.append(int(r, 16))
24
+    if os.path.getsize(sys.argv[n + 1]) == 1296:
25
+        print("binary file format detected. parsing.")
26
+        with open(sys.argv[n + 1], "rb") as f:
27
+            while (byte := f.read(1)):
28
+                frame.append(int.from_bytes(byte, "big"))
29
+    else:
30
+        print("text file format detected. parsing.")
31
+        with open(sys.argv[n + 1]) as f:
32
+            lines = f.readlines()
33
+            for line in lines:
34
+                nums = line.split()
35
+                for r in nums:
36
+                    frame.append(int(r, 16))
29 37
 
30 38
     print("frame length: " + str(len(frame)))
31 39
     row_len = math.sqrt(len(frame))

Loading…
Cancel
Save