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
 
4
 
5
 #include <string.h>
5
 #include <string.h>
6
 #include <stdlib.h>
6
 #include <stdlib.h>
7
+#include <stdio.h>
7
 
8
 
8
 #include "pico/stdlib.h"
9
 #include "pico/stdlib.h"
9
 #include "ff.h"
10
 #include "ff.h"
11
 
12
 
12
 #include "config.h"
13
 #include "config.h"
13
 #include "log.h"
14
 #include "log.h"
15
+#include "debug.h"
14
 #include "fat_disk.h"
16
 #include "fat_disk.h"
15
 
17
 
16
 static uint8_t disk[DISK_BLOCK_COUNT * DISK_BLOCK_SIZE];
18
 static uint8_t disk[DISK_BLOCK_COUNT * DISK_BLOCK_SIZE];
22
         debug("error: f_mkfs returned %d", res);
24
         debug("error: f_mkfs returned %d", res);
23
         return;
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
 uint8_t *fat_disk_get_sector(uint32_t sector) {
67
 uint8_t *fat_disk_get_sector(uint32_t sector) {

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

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
  * Copyright (c) 2019 Ha Thach (tinyusb.org)
6
  * Copyright (c) 2019 Ha Thach (tinyusb.org)
5
  *
7
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy
8
  * Permission is hereby granted, free of charge, to any person obtaining a copy
20
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
  * THE SOFTWARE.
24
  * THE SOFTWARE.
23
- *
24
  */
25
  */
25
 
26
 
26
 #include "bsp/board.h"
27
 #include "bsp/board.h"
63
 // Invoked when received Test Unit Ready command.
64
 // Invoked when received Test Unit Ready command.
64
 // return true allowing host to read/write this LUN e.g SD card inserted
65
 // return true allowing host to read/write this LUN e.g SD card inserted
65
 bool tud_msc_test_unit_ready_cb(uint8_t lun) {
66
 bool tud_msc_test_unit_ready_cb(uint8_t lun) {
66
-    if (ejected || !medium_available) {
67
+    if (!medium_available) {
67
         // Additional Sense 3A-00 is NOT_FOUND
68
         // Additional Sense 3A-00 is NOT_FOUND
68
         tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
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
 // Invoked when received SCSI_CMD_READ_CAPACITY_10 and
75
 // Invoked when received SCSI_CMD_READ_CAPACITY_10 and
78
 void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
78
 void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
79
     (void) lun;
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
 // Invoked when received Start Stop Unit command
90
 // Invoked when received Start Stop Unit command
96
     } else {
101
     } else {
97
         // unload disk storage
102
         // unload disk storage
98
         debug("unload disk storage %d", load_eject);
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
     return true;
109
     return true;
158
     bool in_xfer = true;
165
     bool in_xfer = true;
159
 
166
 
160
     switch (scsi_cmd[0]) {
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
     default:
190
     default:
162
         // Set Sense = Invalid Command Operation
191
         // Set Sense = Invalid Command Operation
163
         tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
192
         tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);

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

4
 import numpy as np
4
 import numpy as np
5
 import sys
5
 import sys
6
 import math
6
 import math
7
+import os
7
 
8
 
8
 if len(sys.argv) < 2:
9
 if len(sys.argv) < 2:
9
     print("Usage:")
10
     print("Usage:")
20
     print("reading " + sys.argv[n + 1])
21
     print("reading " + sys.argv[n + 1])
21
 
22
 
22
     frame = []
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
     print("frame length: " + str(len(frame)))
38
     print("frame length: " + str(len(frame)))
31
     row_len = math.sqrt(len(frame))
39
     row_len = math.sqrt(len(frame))

Loading…
Cancel
Save