소스 검색

Add USB_FLASH_DRIVE_SUPPORT

Marcio Teixeira 6 년 전
부모
커밋
2067619a26
34개의 변경된 파일5717개의 추가작업 그리고 7개의 파일을 삭제
  1. 18
    0
      Marlin/Configuration_adv.h
  2. 4
    0
      Marlin/src/Marlin.cpp
  3. 18
    0
      Marlin/src/config/default/Configuration_adv.h
  4. 0
    1
      Marlin/src/core/macros.h
  5. 2
    0
      Marlin/src/inc/MarlinConfigPre.h
  6. 4
    0
      Marlin/src/inc/SanityCheck.h
  7. 1
    1
      Marlin/src/sd/Sd2Card.cpp
  8. 0
    1
      Marlin/src/sd/Sd2Card.h
  9. 6
    2
      Marlin/src/sd/SdVolume.h
  10. 3
    1
      Marlin/src/sd/cardreader.h
  11. 48
    0
      Marlin/src/sd/usb_flashdrive/SOURCES.txt
  12. 159
    0
      Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp
  13. 91
    0
      Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h
  14. 832
    0
      Marlin/src/sd/usb_flashdrive/lib/Usb.cpp
  15. 52
    0
      Marlin/src/sd/usb_flashdrive/lib/Usb.h
  16. 314
    0
      Marlin/src/sd/usb_flashdrive/lib/UsbCore.h
  17. 290
    0
      Marlin/src/sd/usb_flashdrive/lib/address.h
  18. 217
    0
      Marlin/src/sd/usb_flashdrive/lib/confdescparser.h
  19. 69
    0
      Marlin/src/sd/usb_flashdrive/lib/hexdump.h
  20. 89
    0
      Marlin/src/sd/usb_flashdrive/lib/macros.h
  21. 1282
    0
      Marlin/src/sd/usb_flashdrive/lib/masstorage.cpp
  22. 578
    0
      Marlin/src/sd/usb_flashdrive/lib/masstorage.h
  23. 235
    0
      Marlin/src/sd/usb_flashdrive/lib/max3421e.h
  24. 130
    0
      Marlin/src/sd/usb_flashdrive/lib/message.cpp
  25. 85
    0
      Marlin/src/sd/usb_flashdrive/lib/message.h
  26. 81
    0
      Marlin/src/sd/usb_flashdrive/lib/parsetools.cpp
  27. 147
    0
      Marlin/src/sd/usb_flashdrive/lib/parsetools.h
  28. 91
    0
      Marlin/src/sd/usb_flashdrive/lib/printhex.h
  29. 236
    0
      Marlin/src/sd/usb_flashdrive/lib/settings.h
  30. 173
    0
      Marlin/src/sd/usb_flashdrive/lib/usb_ch9.h
  31. 187
    0
      Marlin/src/sd/usb_flashdrive/usb-2.0-host-library-changes.patch
  32. 213
    0
      Marlin/src/sd/usb_flashdrive/usb_host.cpp
  33. 61
    0
      Marlin/src/sd/usb_flashdrive/usb_host.h
  34. 1
    1
      buildroot/share/tests/megaatmega2560_tests

+ 18
- 0
Marlin/Configuration_adv.h 파일 보기

@@ -683,6 +683,24 @@
683 683
    */
684 684
   //#define AUTO_REPORT_SD_STATUS
685 685
 
686
+  /**
687
+   * Support for USB thumb drives using an Arduino USB Host Shield or
688
+   * equivalent MAX3421E breakout board. The USB thumb drive will appear
689
+   * to Marlin as an SD card.
690
+   *
691
+   * The MAX3421E must be assigned the same pins as the SD card reader, with
692
+   * the following pin mapping:
693
+   *
694
+   *    SCLK, MOSI, MISO --> SCLK, MOSI, MISO
695
+   *    INT              --> SD_DETECT_PIN
696
+   *    SS               --> SDSS
697
+   */
698
+  //#define USB_FLASH_DRIVE_SUPPORT
699
+  #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
700
+    #define USB_CS_PIN         SDSS
701
+    #define USB_INTR_PIN       SD_DETECT_PIN
702
+  #endif
703
+
686 704
 #endif // SDSUPPORT
687 705
 
688 706
 /**

+ 4
- 0
Marlin/src/Marlin.cpp 파일 보기

@@ -593,6 +593,10 @@ void idle(
593 593
       #endif
594 594
     }
595 595
   #endif
596
+
597
+  #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
598
+    Sd2Card::idle();
599
+  #endif
596 600
 }
597 601
 
598 602
 /**

+ 18
- 0
Marlin/src/config/default/Configuration_adv.h 파일 보기

@@ -683,6 +683,24 @@
683 683
    */
684 684
   //#define AUTO_REPORT_SD_STATUS
685 685
 
686
+  /**
687
+   * Support for USB thumb drives using an Arduino USB Host Shield or
688
+   * equivalent MAX3421E breakout board. The USB thumb drive will appear
689
+   * to Marlin as an SD card.
690
+   *
691
+   * The MAX3421E must be assigned the same pins as the SD card reader, with
692
+   * the following pin mapping:
693
+   *
694
+   *    SCLK, MOSI, MISO --> SCLK, MOSI, MISO
695
+   *    INT              --> SD_DETECT_PIN
696
+   *    SS               --> SDSS
697
+   */
698
+  //#define USB_FLASH_DRIVE_SUPPORT
699
+  #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
700
+    #define USB_CS_PIN         SDSS
701
+    #define USB_INTR_PIN       SD_DETECT_PIN
702
+  #endif
703
+
686 704
 #endif // SDSUPPORT
687 705
 
688 706
 /**

+ 0
- 1
Marlin/src/core/macros.h 파일 보기

@@ -19,7 +19,6 @@
19 19
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 20
  *
21 21
  */
22
-
23 22
 #pragma once
24 23
 
25 24
 #include "minmax.h"

+ 2
- 0
Marlin/src/inc/MarlinConfigPre.h 파일 보기

@@ -21,6 +21,8 @@
21 21
  */
22 22
 #pragma once
23 23
 
24
+#define __MARLIN_FIRMWARE__
25
+
24 26
 //
25 27
 // Prefix header to acquire configurations
26 28
 //

+ 4
- 0
Marlin/src/inc/SanityCheck.h 파일 보기

@@ -1830,4 +1830,8 @@ static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too m
1830 1830
   #error "PRINTCOUNTER requires EEPROM_SETTINGS. Please update your Configuration."
1831 1831
 #endif
1832 1832
 
1833
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT) && !(PIN_EXISTS(USB_CS) && PIN_EXISTS(USB_INTR))
1834
+  #error "USB_CS_PIN and USB_INTR_PIN are required for USB_FLASH_DRIVE_SUPPORT."
1835
+#endif
1836
+
1833 1837
 #endif // _SANITYCHECK_H_

+ 1
- 1
Marlin/src/sd/Sd2Card.cpp 파일 보기

@@ -30,7 +30,7 @@
30 30
 
31 31
 #include "../inc/MarlinConfig.h"
32 32
 
33
-#if ENABLED(SDSUPPORT)
33
+#if ENABLED(SDSUPPORT) && DISABLED(USB_FLASH_DRIVE_SUPPORT)
34 34
 
35 35
 /* Enable FAST CRC computations - You can trade speed for FLASH space if
36 36
  * needed by disabling the following define */

+ 0
- 1
Marlin/src/sd/Sd2Card.h 파일 보기

@@ -34,7 +34,6 @@
34 34
 #ifndef _SD2CARD_H_
35 35
 #define _SD2CARD_H_
36 36
 
37
-
38 37
 #include "SdFatConfig.h"
39 38
 #include "SdInfo.h"
40 39
 

+ 6
- 2
Marlin/src/sd/SdVolume.h 파일 보기

@@ -34,10 +34,14 @@
34 34
 #ifndef _SDVOLUME_H_
35 35
 #define _SDVOLUME_H_
36 36
 
37
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
38
+  #include "usb_flashdrive/Sd2Card_FlashDrive.h"
39
+#else
40
+  #include "Sd2Card.h"
41
+#endif
42
+
37 43
 #include "SdFatConfig.h"
38
-#include "Sd2Card.h"
39 44
 #include "SdFatStructs.h"
40
-
41 45
 #include <stdint.h>
42 46
 
43 47
 //==============================================================================

+ 3
- 1
Marlin/src/sd/cardreader.h 파일 보기

@@ -243,7 +243,9 @@ private:
243 243
   #endif
244 244
 };
245 245
 
246
-#if PIN_EXISTS(SD_DETECT)
246
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
247
+  #define IS_SD_INSERTED Sd2Card::isInserted()
248
+#elif PIN_EXISTS(SD_DETECT)
247 249
   #if ENABLED(SD_DETECT_INVERTED)
248 250
     #define IS_SD_INSERTED (READ(SD_DETECT_PIN) == HIGH)
249 251
   #else

+ 48
- 0
Marlin/src/sd/usb_flashdrive/SOURCES.txt 파일 보기

@@ -0,0 +1,48 @@
1
+
2
+==== SUMMARY ====
3
+
4
+Source Path:                           Repository:                           License:
5
+------------                           -----------                           --------
6
+usb_flashdrive/lib                     github.com/felis/USB_Host_Shield_2.0  GPLv2 or later
7
+usb_flashdrive/lib/masstorage.cpp [1]  github.com/greiman/UsbFat             MIT
8
+usb_flashdrive/lib/settings.h [1]      github.com/greiman/UsbFat             MIT
9
+
10
+[1] Changes related to SKIP_WRITE_PROTECT and DELAY only
11
+
12
+
13
+==== USB HOST SHIELD 2.0 LIBRARY ====
14
+
15
+The lib/ folder contains a subset of the files from the USB Host Shield 2.0
16
+library:
17
+
18
+  https://github.com/felis/USB_Host_Shield_2.0
19
+
20
+While the original library was released under the GPLv2 and could not be
21
+commingled with Marlin, the developers have graciously re-licenced the
22
+files needed for Marlin as "GPLv2 or later", as documented in this thread.
23
+
24
+  https://github.com/felis/USB_Host_Shield_2.0/issues/364
25
+
26
+Small modifications have been made to the source. Please search for
27
+USB_FLASH_DRIVE_SUPPORT or look at the patch file to see what was changed.
28
+
29
+
30
+==== PERFORMANCE ENHANCEMENTS FOR USB DRIVES ====
31
+
32
+There are also some small performance enhancements from Bill Greiman, regarding
33
+SKIP_WRITE_PROTECT and DELAY. These changes came from the following repo:
34
+
35
+   https://github.com/greiman/UsbFat
36
+
37
+While the original library was released under the GPLv2 and could not be
38
+commingled with Marlin, the developer has graciously re-licenced his changes
39
+under the "MIT" license, as documented here:
40
+
41
+   https://github.com/greiman/UsbFat/issues/8
42
+
43
+==== MARLIN INTEGRATION WORK ====
44
+
45
+All additional work done to integrate USB into Marlin was performed by AlephObjects, Inc.
46
+and is licensed under the GPLv3.
47
+
48
+-- marcio@alephobjects.com

+ 159
- 0
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp 파일 보기

@@ -0,0 +1,159 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../inc/MarlinConfigPre.h"
24
+
25
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
26
+
27
+#include "lib/Usb.h"
28
+#include "lib/masstorage.h"
29
+
30
+#include "Sd2Card_FlashDrive.h"
31
+
32
+#include <SPI.h>
33
+
34
+#include "../../core/serial.h"
35
+
36
+USB usb;
37
+BulkOnly bulk(&usb);
38
+
39
+Sd2Card::state_t Sd2Card::state;
40
+uint32_t         Sd2Card::block;
41
+
42
+bool Sd2Card::usbHostReady() {
43
+  return state == USB_HOST_INITIALIZED;
44
+}
45
+
46
+bool Sd2Card::isInserted() {
47
+  return usb.getUsbTaskState() == USB_STATE_RUNNING;
48
+}
49
+
50
+// Marlin calls this whenever an SD card is detected, so this method
51
+// should not be used to initialize the USB host library
52
+bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
53
+  if (!usbHostReady()) return false;
54
+
55
+  if (!bulk.LUNIsGood(0)) {
56
+    SERIAL_ECHOLNPGM("LUN zero is not good\n");
57
+    return false;
58
+  }
59
+
60
+  SERIAL_ECHOLNPAIR("LUN Capacity: ",bulk.GetCapacity(0));
61
+
62
+  const uint32_t sectorSize = bulk.GetSectorSize(0);
63
+  if (sectorSize != 512) {
64
+    SERIAL_ECHOLNPAIR("Expecting sector size of 512, got: ",sectorSize);
65
+    return false;
66
+  }
67
+
68
+  return true;
69
+}
70
+
71
+void Sd2Card::idle() {
72
+  static uint32_t next_retry;
73
+
74
+  switch (state) {
75
+    case USB_HOST_DELAY_INIT:
76
+      next_retry = millis() + 10000;
77
+      state = USB_HOST_WAITING;
78
+      break;
79
+    case USB_HOST_WAITING:
80
+      if (millis() > next_retry) {
81
+        next_retry = millis() + 10000;
82
+        state = USB_HOST_UNINITIALIZED;
83
+      }
84
+      break;
85
+    case USB_HOST_UNINITIALIZED:
86
+      SERIAL_ECHOLNPGM("Starting USB host");
87
+      if (!usb.start()) {
88
+        SERIAL_ECHOLNPGM("USB host failed to start. Will retry in 10 seconds.");
89
+        state = USB_HOST_DELAY_INIT;
90
+      }
91
+      else {
92
+        SERIAL_ECHOLNPGM("USB host initialized");
93
+        state = USB_HOST_INITIALIZED;
94
+      }
95
+      break;
96
+    case USB_HOST_INITIALIZED:
97
+      const uint8_t lastUsbTaskState = usb.getUsbTaskState();
98
+      usb.Task();
99
+      const uint8_t newUsbTaskState  = usb.getUsbTaskState();
100
+
101
+      if (lastUsbTaskState == USB_STATE_RUNNING && newUsbTaskState != USB_STATE_RUNNING) {
102
+        // the user pulled the flash drive. Make sure the bulk storage driver releases the address
103
+        SERIAL_ECHOLNPGM("Drive removed\n");
104
+        //bulk.Release();
105
+      }
106
+      if (lastUsbTaskState != USB_STATE_RUNNING && newUsbTaskState == USB_STATE_RUNNING)
107
+        SERIAL_ECHOLNPGM("Drive inserted\n");
108
+      break;
109
+  }
110
+}
111
+
112
+uint32_t Sd2Card::cardSize() {
113
+  if (!usbHostReady()) return 0;
114
+  return bulk.GetCapacity(0);
115
+}
116
+
117
+bool Sd2Card::readData(uint8_t* dst) {
118
+  return readBlock(block++, dst);
119
+}
120
+
121
+bool Sd2Card::readStart(uint32_t blockNumber) {
122
+  block = blockNumber;
123
+  return true;
124
+}
125
+
126
+bool Sd2Card::readStop() {
127
+  return usbHostReady();
128
+}
129
+
130
+bool Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
131
+  if (!usbHostReady()) {
132
+    SERIAL_ECHOLNPGM("Read from uninitalized USB host");
133
+    return false;
134
+  }
135
+  return bulk.Read(0, block, 512, 1, dst) == 0;
136
+}
137
+
138
+bool Sd2Card::writeData(const uint8_t* src) {
139
+  return writeBlock(block++, src);
140
+}
141
+
142
+bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
143
+  block = blockNumber;
144
+  return true;
145
+}
146
+
147
+bool Sd2Card::writeStop() {
148
+  return usbHostReady();
149
+}
150
+
151
+bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
152
+  if (!usbHostReady()) {
153
+    SERIAL_ECHOLNPGM("Write to uninitalized USB host");
154
+    return false;
155
+  }
156
+  return bulk.Write(0, blockNumber, 512, 1, src) == 0;
157
+}
158
+
159
+#endif // USB_FLASH_DRIVE_SUPPORT

+ 91
- 0
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h 파일 보기

@@ -0,0 +1,91 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * \file
25
+ * \brief Sd2Card class for V2 SD/SDHC cards
26
+ */
27
+
28
+#ifndef _SD2CARD_FLASHDRIVE_H_
29
+#define _SD2CARD_FLASHDRIVE_H_
30
+
31
+#include "../SdFatConfig.h"
32
+#include "../SdInfo.h"
33
+
34
+/**
35
+ * define SOFTWARE_SPI to use bit-bang SPI
36
+ */
37
+#if MEGA_SOFT_SPI || USE_SOFTWARE_SPI
38
+  #define SOFTWARE_SPI
39
+#endif
40
+
41
+// SPI pin definitions - do not edit here - change in SdFatConfig.h
42
+#if DISABLED(SOFTWARE_SPI)
43
+  // hardware pin defs
44
+  #define SD_CHIP_SELECT_PIN  SS_PIN            // The default chip select pin for the SD card is SS.
45
+  // The following three pins must not be redefined for hardware SPI.
46
+  #define SPI_MOSI_PIN        MOSI_PIN          // SPI Master Out Slave In pin
47
+  #define SPI_MISO_PIN        MISO_PIN          // SPI Master In Slave Out pin
48
+  #define SPI_SCK_PIN         SCK_PIN           // SPI Clock pin
49
+#else  // SOFTWARE_SPI
50
+  #define SD_CHIP_SELECT_PIN  SOFT_SPI_CS_PIN   // SPI chip select pin
51
+  #define SPI_MOSI_PIN        SOFT_SPI_MOSI_PIN // SPI Master Out Slave In pin
52
+  #define SPI_MISO_PIN        SOFT_SPI_MISO_PIN // SPI Master In Slave Out pin
53
+  #define SPI_SCK_PIN         SOFT_SPI_SCK_PIN  // SPI Clock pin
54
+#endif // SOFTWARE_SPI
55
+
56
+class Sd2Card {
57
+  private:
58
+
59
+    typedef enum {
60
+      USB_HOST_DELAY_INIT,
61
+      USB_HOST_WAITING,
62
+      USB_HOST_UNINITIALIZED,
63
+      USB_HOST_INITIALIZED
64
+    } state_t;
65
+
66
+    static state_t  state;
67
+    static uint32_t block;
68
+
69
+    static bool usbHostReady();
70
+
71
+  public:
72
+    static void idle();
73
+
74
+    static bool isInserted();
75
+
76
+    uint32_t cardSize();
77
+
78
+    bool init(uint8_t sckRateID = 0, uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
79
+
80
+    bool readData(uint8_t* dst);
81
+    bool readStart(uint32_t blockNumber);
82
+    bool readStop();
83
+    bool readBlock(uint32_t block, uint8_t* dst);
84
+
85
+    bool writeData(const uint8_t* src);
86
+    bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
87
+    bool writeStop();
88
+    bool writeBlock(uint32_t blockNumber, const uint8_t* src);
89
+};
90
+
91
+#endif  // _SD2CARD_FLASHDRIVE_H_

+ 832
- 0
Marlin/src/sd/usb_flashdrive/lib/Usb.cpp 파일 보기

@@ -0,0 +1,832 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+/* USB functions */
25
+
26
+#include "../../../inc/MarlinConfigPre.h"
27
+
28
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
29
+
30
+#include "Usb.h"
31
+
32
+static uint8_t usb_error = 0;
33
+static uint8_t usb_task_state;
34
+
35
+/* constructor */
36
+USB::USB() : bmHubPre(0) {
37
+        usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine
38
+        init();
39
+}
40
+
41
+/* Initialize data structures */
42
+void USB::init() {
43
+        //devConfigIndex = 0;
44
+        bmHubPre = 0;
45
+}
46
+
47
+uint8_t USB::getUsbTaskState(void) {
48
+        return ( usb_task_state);
49
+}
50
+
51
+void USB::setUsbTaskState(uint8_t state) {
52
+        usb_task_state = state;
53
+}
54
+
55
+EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
56
+        UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
57
+
58
+        if(!p || !p->epinfo)
59
+                return NULL;
60
+
61
+        EpInfo *pep = p->epinfo;
62
+
63
+        for(uint8_t i = 0; i < p->epcount; i++) {
64
+                if((pep)->epAddr == ep)
65
+                        return pep;
66
+
67
+                pep++;
68
+        }
69
+        return NULL;
70
+}
71
+
72
+/* set device table entry */
73
+
74
+/* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
75
+uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) {
76
+        if(!eprecord_ptr)
77
+                return USB_ERROR_INVALID_ARGUMENT;
78
+
79
+        UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
80
+
81
+        if(!p)
82
+                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
83
+
84
+        p->address.devAddress = addr;
85
+        p->epinfo = eprecord_ptr;
86
+        p->epcount = epcount;
87
+
88
+        return 0;
89
+}
90
+
91
+uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit) {
92
+        UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
93
+
94
+        if(!p)
95
+                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
96
+
97
+        if(!p->epinfo)
98
+                return USB_ERROR_EPINFO_IS_NULL;
99
+
100
+        *ppep = getEpInfoEntry(addr, ep);
101
+
102
+        if(!*ppep)
103
+                return USB_ERROR_EP_NOT_FOUND_IN_TBL;
104
+
105
+        *nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower));
106
+        (*nak_limit)--;
107
+        /*
108
+          USBTRACE2("\r\nAddress: ", addr);
109
+          USBTRACE2(" EP: ", ep);
110
+          USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower);
111
+          USBTRACE2(" NAK Limit: ", nak_limit);
112
+          USBTRACE("\r\n");
113
+         */
114
+        regWr(rPERADDR, addr); //set peripheral address
115
+
116
+        uint8_t mode = regRd(rMODE);
117
+
118
+        //Serial.print("\r\nMode: ");
119
+        //Serial.println( mode, HEX);
120
+        //Serial.print("\r\nLS: ");
121
+        //Serial.println(p->lowspeed, HEX);
122
+
123
+
124
+
125
+        // Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
126
+        regWr(rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
127
+
128
+        return 0;
129
+}
130
+
131
+/* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer,   */
132
+/* depending on request. Actual requests are defined as inlines                                                                                      */
133
+/* return codes:                */
134
+/* 00       =   success         */
135
+
136
+/* 01-0f    =   non-zero HRSLT  */
137
+uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
138
+        uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) {
139
+        bool direction = false; //request direction, IN or OUT
140
+        uint8_t rcode;
141
+        SETUP_PKT setup_pkt;
142
+
143
+        EpInfo *pep = NULL;
144
+        uint16_t nak_limit = 0;
145
+
146
+        rcode = SetAddress(addr, ep, &pep, &nak_limit);
147
+
148
+        if(rcode)
149
+                return rcode;
150
+
151
+        direction = ((bmReqType & 0x80) > 0);
152
+
153
+        /* fill in setup packet */
154
+        setup_pkt.ReqType_u.bmRequestType = bmReqType;
155
+        setup_pkt.bRequest = bRequest;
156
+        setup_pkt.wVal_u.wValueLo = wValLo;
157
+        setup_pkt.wVal_u.wValueHi = wValHi;
158
+        setup_pkt.wIndex = wInd;
159
+        setup_pkt.wLength = total;
160
+
161
+        bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO
162
+
163
+        rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
164
+
165
+        if(rcode) //return HRSLT if not zero
166
+                return ( rcode);
167
+
168
+        if(dataptr != NULL) //data stage, if present
169
+        {
170
+                if(direction) //IN transfer
171
+                {
172
+                        uint16_t left = total;
173
+
174
+                        pep->bmRcvToggle = 1; //bmRCVTOG1;
175
+
176
+                        while(left) {
177
+                                // Bytes read into buffer
178
+                                uint16_t read = nbytes;
179
+                                //uint16_t read = (left<nbytes) ? left : nbytes;
180
+
181
+                                rcode = InTransfer(pep, nak_limit, &read, dataptr);
182
+                                if(rcode == hrTOGERR) {
183
+                                        // yes, we flip it wrong here so that next time it is actually correct!
184
+                                        pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
185
+                                        continue;
186
+                                }
187
+
188
+                                if(rcode)
189
+                                        return rcode;
190
+
191
+                                // Invoke callback function if inTransfer completed successfully and callback function pointer is specified
192
+                                if(!rcode && p)
193
+                                        ((USBReadParser*)p)->Parse(read, dataptr, total - left);
194
+
195
+                                left -= read;
196
+
197
+                                if(read < nbytes)
198
+                                        break;
199
+                        }
200
+                } else //OUT transfer
201
+                {
202
+                        pep->bmSndToggle = 1; //bmSNDTOG1;
203
+                        rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
204
+                }
205
+                if(rcode) //return error
206
+                        return ( rcode);
207
+        }
208
+        // Status stage
209
+        return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction
210
+}
211
+
212
+/* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
213
+/* Keep sending INs and writes data to memory area pointed by 'data'                                                           */
214
+
215
+/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
216
+            fe USB xfer timeout */
217
+uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) {
218
+        EpInfo *pep = NULL;
219
+        uint16_t nak_limit = 0;
220
+
221
+        uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
222
+
223
+        if(rcode) {
224
+                USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
225
+                USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
226
+                USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81);
227
+                return rcode;
228
+        }
229
+        return InTransfer(pep, nak_limit, nbytesptr, data, bInterval);
230
+}
231
+
232
+uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) {
233
+        uint8_t rcode = 0;
234
+        uint8_t pktsize;
235
+
236
+        uint16_t nbytes = *nbytesptr;
237
+        //printf("Requesting %i bytes ", nbytes);
238
+        uint8_t maxpktsize = pep->maxPktSize;
239
+
240
+        *nbytesptr = 0;
241
+        regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
242
+
243
+        // use a 'break' to exit this loop
244
+        while(1) {
245
+                rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
246
+                if(rcode == hrTOGERR) {
247
+                        // yes, we flip it wrong here so that next time it is actually correct!
248
+                        pep->bmRcvToggle = (regRd(rHRSL) & bmRCVTOGRD) ? 0 : 1;
249
+                        regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
250
+                        continue;
251
+                }
252
+                if(rcode) {
253
+                        //printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
254
+                        break; //should be 0, indicating ACK. Else return error code.
255
+                }
256
+                /* check for RCVDAVIRQ and generate error if not present */
257
+                /* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
258
+                if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
259
+                        //printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
260
+                        rcode = 0xf0; //receive error
261
+                        break;
262
+                }
263
+                pktsize = regRd(rRCVBC); //number of received bytes
264
+                //printf("Got %i bytes \r\n", pktsize);
265
+                // This would be OK, but...
266
+                //assert(pktsize <= nbytes);
267
+                if(pktsize > nbytes) {
268
+                        // This can happen. Use of assert on Arduino locks up the Arduino.
269
+                        // So I will trim the value, and hope for the best.
270
+                        //printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
271
+                        pktsize = nbytes;
272
+                }
273
+
274
+                int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
275
+
276
+                if(mem_left < 0)
277
+                        mem_left = 0;
278
+
279
+                data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
280
+
281
+                regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer
282
+                *nbytesptr += pktsize; // add this packet's byte count to total transfer length
283
+
284
+                /* The transfer is complete under two conditions:           */
285
+                /* 1. The device sent a short packet (L.T. maxPacketSize)   */
286
+                /* 2. 'nbytes' have been transferred.                       */
287
+                if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
288
+                {
289
+                        // Save toggle value
290
+                        pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
291
+                        //printf("\r\n");
292
+                        rcode = 0;
293
+                        break;
294
+                } else if(bInterval > 0)
295
+                        delay(bInterval); // Delay according to polling interval
296
+        } //while( 1 )
297
+        return ( rcode);
298
+}
299
+
300
+/* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
301
+/* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer   */
302
+
303
+/* rcode 0 if no errors. rcode 01-0f is relayed from HRSL                       */
304
+uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
305
+        EpInfo *pep = NULL;
306
+        uint16_t nak_limit = 0;
307
+
308
+        uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
309
+
310
+        if(rcode)
311
+                return rcode;
312
+
313
+        return OutTransfer(pep, nak_limit, nbytes, data);
314
+}
315
+
316
+uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data) {
317
+        uint8_t rcode = hrSUCCESS, retry_count;
318
+        uint8_t *data_p = data; //local copy of the data pointer
319
+        uint16_t bytes_tosend, nak_count;
320
+        uint16_t bytes_left = nbytes;
321
+
322
+        uint8_t maxpktsize = pep->maxPktSize;
323
+
324
+        if(maxpktsize < 1 || maxpktsize > 64)
325
+                return USB_ERROR_INVALID_MAX_PKT_SIZE;
326
+
327
+        uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
328
+
329
+        regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
330
+
331
+        while(bytes_left) {
332
+                retry_count = 0;
333
+                nak_count = 0;
334
+                bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
335
+                bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
336
+                regWr(rSNDBC, bytes_tosend); //set number of bytes
337
+                regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
338
+                while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
339
+                regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
340
+                rcode = (regRd(rHRSL) & 0x0f);
341
+
342
+                while(rcode && ((int32_t)((uint32_t)millis() - timeout) < 0L)) {
343
+                        switch(rcode) {
344
+                                case hrNAK:
345
+                                        nak_count++;
346
+                                        if(nak_limit && (nak_count == nak_limit))
347
+                                                goto breakout;
348
+                                        //return ( rcode);
349
+                                        break;
350
+                                case hrTIMEOUT:
351
+                                        retry_count++;
352
+                                        if(retry_count == USB_RETRY_LIMIT)
353
+                                                goto breakout;
354
+                                        //return ( rcode);
355
+                                        break;
356
+                                case hrTOGERR:
357
+                                        // yes, we flip it wrong here so that next time it is actually correct!
358
+                                        pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
359
+                                        regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
360
+                                        break;
361
+                                default:
362
+                                        goto breakout;
363
+                        }//switch( rcode
364
+
365
+                        /* process NAK according to Host out NAK bug */
366
+                        regWr(rSNDBC, 0);
367
+                        regWr(rSNDFIFO, *data_p);
368
+                        regWr(rSNDBC, bytes_tosend);
369
+                        regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
370
+                        while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
371
+                        regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
372
+                        rcode = (regRd(rHRSL) & 0x0f);
373
+                }//while( rcode && ....
374
+                bytes_left -= bytes_tosend;
375
+                data_p += bytes_tosend;
376
+        }//while( bytes_left...
377
+breakout:
378
+
379
+        pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0;  //update toggle
380
+        return ( rcode); //should be 0 in all cases
381
+}
382
+/* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty       */
383
+/* If NAK, tries to re-send up to nak_limit times                                                   */
384
+/* If nak_limit == 0, do not count NAKs, exit after timeout                                         */
385
+/* If bus timeout, re-sends up to USB_RETRY_LIMIT times                                             */
386
+
387
+/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout                       */
388
+uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
389
+        uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
390
+        uint8_t tmpdata;
391
+        uint8_t rcode = hrSUCCESS;
392
+        uint8_t retry_count = 0;
393
+        uint16_t nak_count = 0;
394
+
395
+        while((int32_t)((uint32_t)millis() - timeout) < 0L) {
396
+#if defined(ESP8266) || defined(ESP32)
397
+                        yield(); // needed in order to reset the watchdog timer on the ESP8266
398
+#endif
399
+                regWr(rHXFR, (token | ep)); //launch the transfer
400
+                rcode = USB_ERROR_TRANSFER_TIMEOUT;
401
+
402
+                while((int32_t)((uint32_t)millis() - timeout) < 0L) //wait for transfer completion
403
+                {
404
+#if defined(ESP8266) || defined(ESP32)
405
+                        yield(); // needed in order to reset the watchdog timer on the ESP8266
406
+#endif
407
+                        tmpdata = regRd(rHIRQ);
408
+
409
+                        if(tmpdata & bmHXFRDNIRQ) {
410
+                                regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
411
+                                rcode = 0x00;
412
+                                break;
413
+                        }//if( tmpdata & bmHXFRDNIRQ
414
+
415
+                }//while ( millis() < timeout
416
+
417
+                //if (rcode != 0x00) //exit if timeout
418
+                //        return ( rcode);
419
+
420
+                rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
421
+
422
+                switch(rcode) {
423
+                        case hrNAK:
424
+                                nak_count++;
425
+                                if(nak_limit && (nak_count == nak_limit))
426
+                                        return (rcode);
427
+                                break;
428
+                        case hrTIMEOUT:
429
+                                retry_count++;
430
+                                if(retry_count == USB_RETRY_LIMIT)
431
+                                        return (rcode);
432
+                                break;
433
+                        default:
434
+                                return (rcode);
435
+                }//switch( rcode
436
+
437
+        }//while( timeout > millis()
438
+        return ( rcode);
439
+}
440
+
441
+/* USB main task. Performs enumeration/cleanup */
442
+void USB::Task(void) //USB state machine
443
+{
444
+        uint8_t rcode;
445
+        uint8_t tmpdata;
446
+        static uint32_t delay = 0;
447
+        //USB_DEVICE_DESCRIPTOR buf;
448
+        bool lowspeed = false;
449
+
450
+        MAX3421E::Task();
451
+
452
+        tmpdata = getVbusState();
453
+
454
+        /* modify USB task state if Vbus changed */
455
+        switch(tmpdata) {
456
+                case SE1: //illegal state
457
+                        usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
458
+                        lowspeed = false;
459
+                        break;
460
+                case SE0: //disconnected
461
+                        if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
462
+                                usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
463
+                        lowspeed = false;
464
+                        break;
465
+                case LSHOST:
466
+
467
+                        lowspeed = true;
468
+                        //intentional fallthrough
469
+                case FSHOST: //attached
470
+                        if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
471
+                                delay = (uint32_t)millis() + USB_SETTLE_DELAY;
472
+                                usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
473
+                        }
474
+                        break;
475
+        }// switch( tmpdata
476
+
477
+        for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
478
+                if(devConfig[i])
479
+                        rcode = devConfig[i]->Poll();
480
+
481
+        switch(usb_task_state) {
482
+                case USB_DETACHED_SUBSTATE_INITIALIZE:
483
+                        init();
484
+
485
+                        for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
486
+                                if(devConfig[i])
487
+                                        rcode = devConfig[i]->Release();
488
+
489
+                        usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
490
+                        break;
491
+                case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
492
+                        break;
493
+                case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
494
+                        break;
495
+                case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
496
+                        if((int32_t)((uint32_t)millis() - delay) >= 0L)
497
+                                usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
498
+                        else break; // don't fall through
499
+                case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
500
+                        regWr(rHCTL, bmBUSRST); //issue bus reset
501
+                        usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
502
+                        break;
503
+                case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
504
+                        if((regRd(rHCTL) & bmBUSRST) == 0) {
505
+                                tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
506
+                                regWr(rMODE, tmpdata);
507
+                                usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
508
+                                //delay = (uint32_t)millis() + 20; //20ms wait after reset per USB spec
509
+                        }
510
+                        break;
511
+                case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
512
+                        if(regRd(rHIRQ) & bmFRAMEIRQ) {
513
+                                //when first SOF received _and_ 20ms has passed we can continue
514
+                                /*
515
+                                if (delay < (uint32_t)millis()) //20ms passed
516
+                                        usb_task_state = USB_STATE_CONFIGURING;
517
+                                 */
518
+                                usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
519
+                                delay = (uint32_t)millis() + 20;
520
+                        }
521
+                        break;
522
+                case USB_ATTACHED_SUBSTATE_WAIT_RESET:
523
+                        if((int32_t)((uint32_t)millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING;
524
+                        else break; // don't fall through
525
+                case USB_STATE_CONFIGURING:
526
+
527
+                        //Serial.print("\r\nConf.LS: ");
528
+                        //Serial.println(lowspeed, HEX);
529
+
530
+                        rcode = Configuring(0, 0, lowspeed);
531
+
532
+                        if(rcode) {
533
+                                if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
534
+                                        usb_error = rcode;
535
+                                        usb_task_state = USB_STATE_ERROR;
536
+                                }
537
+                        } else
538
+                                usb_task_state = USB_STATE_RUNNING;
539
+                        break;
540
+                case USB_STATE_RUNNING:
541
+                        break;
542
+                case USB_STATE_ERROR:
543
+                        //MAX3421E::Init();
544
+                        break;
545
+        } // switch( usb_task_state )
546
+}
547
+
548
+uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
549
+        //uint8_t                buf[12];
550
+        uint8_t rcode;
551
+        UsbDevice *p0 = NULL, *p = NULL;
552
+
553
+        // Get pointer to pseudo device with address 0 assigned
554
+        p0 = addrPool.GetUsbDevicePtr(0);
555
+
556
+        if(!p0)
557
+                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
558
+
559
+        if(!p0->epinfo)
560
+                return USB_ERROR_EPINFO_IS_NULL;
561
+
562
+        p0->lowspeed = (lowspeed) ? true : false;
563
+
564
+        // Allocate new address according to device class
565
+        uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
566
+
567
+        if(!bAddress)
568
+                return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
569
+
570
+        p = addrPool.GetUsbDevicePtr(bAddress);
571
+
572
+        if(!p)
573
+                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
574
+
575
+        p->lowspeed = lowspeed;
576
+
577
+        // Assign new address to the device
578
+        rcode = setAddr(0, 0, bAddress);
579
+
580
+        if(rcode) {
581
+                addrPool.FreeAddress(bAddress);
582
+                bAddress = 0;
583
+                return rcode;
584
+        }
585
+        return 0;
586
+};
587
+
588
+uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
589
+        //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
590
+        uint8_t retries = 0;
591
+
592
+again:
593
+        uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
594
+        if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
595
+                if(parent == 0) {
596
+                        // Send a bus reset on the root interface.
597
+                        regWr(rHCTL, bmBUSRST); //issue bus reset
598
+                        delay(102); // delay 102ms, compensate for clock inaccuracy.
599
+                } else {
600
+                        // reset parent port
601
+                        devConfig[parent]->ResetHubPort(port);
602
+                }
603
+        } else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
604
+                delay(100);
605
+                retries++;
606
+                goto again;
607
+        } else if(rcode)
608
+                return rcode;
609
+
610
+        rcode = devConfig[driver]->Init(parent, port, lowspeed);
611
+        if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
612
+                delay(100);
613
+                retries++;
614
+                goto again;
615
+        }
616
+        if(rcode) {
617
+                // Issue a bus reset, because the device may be in a limbo state
618
+                if(parent == 0) {
619
+                        // Send a bus reset on the root interface.
620
+                        regWr(rHCTL, bmBUSRST); //issue bus reset
621
+                        delay(102); // delay 102ms, compensate for clock inaccuracy.
622
+                } else {
623
+                        // reset parent port
624
+                        devConfig[parent]->ResetHubPort(port);
625
+                }
626
+        }
627
+        return rcode;
628
+}
629
+
630
+/*
631
+ * This is broken. We need to enumerate differently.
632
+ * It causes major problems with several devices if detected in an unexpected order.
633
+ *
634
+ *
635
+ * Oleg - I wouldn't do anything before the newly connected device is considered sane.
636
+ * i.e.(delays are not indicated for brevity):
637
+ * 1. reset
638
+ * 2. GetDevDescr();
639
+ * 3a. If ACK, continue with allocating address, addressing, etc.
640
+ * 3b. Else reset again, count resets, stop at some number (5?).
641
+ * 4. When max.number of resets is reached, toggle power/fail
642
+ * If desired, this could be modified by performing two resets with GetDevDescr() in the middle - however, from my experience, if a device answers to GDD()
643
+ * it doesn't need to be reset again
644
+ * New steps proposal:
645
+ * 1: get address pool instance. exit on fail
646
+ * 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail.
647
+ * 3: bus reset, 100ms delay
648
+ * 4: set address
649
+ * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail
650
+ * 6: while (configurations) {
651
+ *              for(each configuration) {
652
+ *                      for (each driver) {
653
+ *                              6a: Ask device if it likes configuration. Returns 0 on OK.
654
+ *                                      If successful, the driver configured device.
655
+ *                                      The driver now owns the endpoints, and takes over managing them.
656
+ *                                      The following will need codes:
657
+ *                                          Everything went well, instance consumed, exit with success.
658
+ *                                          Instance already in use, ignore it, try next driver.
659
+ *                                          Not a supported device, ignore it, try next driver.
660
+ *                                          Not a supported configuration for this device, ignore it, try next driver.
661
+ *                                          Could not configure device, fatal, exit with fail.
662
+ *                      }
663
+ *              }
664
+ *    }
665
+ * 7: for(each driver) {
666
+ *      7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID
667
+ * 8: if we get here, no driver likes the device plugged in, so exit failure.
668
+ *
669
+ */
670
+uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
671
+        //uint8_t bAddress = 0;
672
+        //printf("Configuring: parent = %i, port = %i\r\n", parent, port);
673
+        uint8_t devConfigIndex;
674
+        uint8_t rcode = 0;
675
+        uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
676
+        USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
677
+        UsbDevice *p = NULL;
678
+        EpInfo *oldep_ptr = NULL;
679
+        EpInfo epInfo;
680
+
681
+        epInfo.epAddr = 0;
682
+        epInfo.maxPktSize = 8;
683
+        epInfo.bmSndToggle = 0;
684
+        epInfo.bmRcvToggle = 0;
685
+        epInfo.bmNakPower = USB_NAK_MAX_POWER;
686
+
687
+        //delay(2000);
688
+        AddressPool &addrPool = GetAddressPool();
689
+        // Get pointer to pseudo device with address 0 assigned
690
+        p = addrPool.GetUsbDevicePtr(0);
691
+        if(!p) {
692
+                //printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
693
+                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
694
+        }
695
+
696
+        // Save old pointer to EP_RECORD of address 0
697
+        oldep_ptr = p->epinfo;
698
+
699
+        // Temporary assign new pointer to epInfo to p->epinfo in order to
700
+        // avoid toggle inconsistence
701
+
702
+        p->epinfo = &epInfo;
703
+
704
+        p->lowspeed = lowspeed;
705
+        // Get device descriptor
706
+        rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
707
+
708
+        // Restore p->epinfo
709
+        p->epinfo = oldep_ptr;
710
+
711
+        if(rcode) {
712
+                //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
713
+                return rcode;
714
+        }
715
+
716
+        // to-do?
717
+        // Allocate new address according to device class
718
+        //bAddress = addrPool.AllocAddress(parent, false, port);
719
+
720
+        uint16_t vid = udd->idVendor;
721
+        uint16_t pid = udd->idProduct;
722
+        uint8_t klass = udd->bDeviceClass;
723
+        uint8_t subklass = udd->bDeviceSubClass;
724
+        // Attempt to configure if VID/PID or device class matches with a driver
725
+        // Qualify with subclass too.
726
+        //
727
+        // VID/PID & class tests default to false for drivers not yet ported
728
+        // subclass defaults to true, so you don't have to define it if you don't have to.
729
+        //
730
+        for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
731
+                if(!devConfig[devConfigIndex]) continue; // no driver
732
+                if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
733
+                if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) {
734
+                        rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
735
+                        if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
736
+                                break;
737
+                }
738
+        }
739
+
740
+        if(devConfigIndex < USB_NUMDEVICES) {
741
+                return rcode;
742
+        }
743
+
744
+
745
+        // blindly attempt to configure
746
+        for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
747
+                if(!devConfig[devConfigIndex]) continue;
748
+                if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
749
+                if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above
750
+                rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
751
+
752
+                //printf("ERROR ENUMERATING %2.2x\r\n", rcode);
753
+                if(!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
754
+                        // in case of an error dev_index should be reset to 0
755
+                        //                in order to start from the very beginning the
756
+                        //                next time the program gets here
757
+                        //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
758
+                        //        devConfigIndex = 0;
759
+                        return rcode;
760
+                }
761
+        }
762
+        // if we get here that means that the device class is not supported by any of registered classes
763
+        rcode = DefaultAddressing(parent, port, lowspeed);
764
+
765
+        return rcode;
766
+}
767
+
768
+uint8_t USB::ReleaseDevice(uint8_t addr) {
769
+        if(!addr)
770
+                return 0;
771
+
772
+        for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
773
+                if(!devConfig[i]) continue;
774
+                if(devConfig[i]->GetAddress() == addr)
775
+                        return devConfig[i]->Release();
776
+        }
777
+        return 0;
778
+}
779
+
780
+#if 1 //!defined(USB_METHODS_INLINE)
781
+//get device descriptor
782
+
783
+uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
784
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL));
785
+}
786
+//get configuration descriptor
787
+
788
+uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
789
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL));
790
+}
791
+
792
+/* Requests Configuration Descriptor. Sends two Get Conf Descr requests. The first one gets the total length of all descriptors, then the second one requests this
793
+ total length. The length of the first request can be shorter ( 4 bytes ), however, there are devices which won't work unless this length is set to 9 */
794
+uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) {
795
+        const uint8_t bufSize = 64;
796
+        uint8_t buf[bufSize];
797
+        USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
798
+
799
+        uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
800
+
801
+        if(ret)
802
+                return ret;
803
+
804
+        uint16_t total = ucd->wTotalLength;
805
+
806
+        //USBTRACE2("\r\ntotal conf.size:", total);
807
+
808
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p));
809
+}
810
+
811
+//get string descriptor
812
+
813
+uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
814
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL));
815
+}
816
+//set address
817
+
818
+uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
819
+        uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL);
820
+        //delay(2); //per USB 2.0 sect.9.2.6.3
821
+        delay(300); // Older spec says you should wait at least 200ms
822
+        return rcode;
823
+        //return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
824
+}
825
+//set configuration
826
+
827
+uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
828
+        return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
829
+}
830
+
831
+#endif // defined(USB_METHODS_INLINE)
832
+#endif // USB_FLASH_DRIVE_SUPPORT

+ 52
- 0
Marlin/src/sd/usb_flashdrive/lib/Usb.h 파일 보기

@@ -0,0 +1,52 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+/* USB functions */
25
+#ifndef _usb_h_
26
+#define _usb_h_
27
+
28
+#include "../../../inc/MarlinConfigPre.h"
29
+
30
+// WARNING: Do not change the order of includes, or stuff will break!
31
+#include <inttypes.h>
32
+#include <stddef.h>
33
+#include <stdio.h>
34
+
35
+// None of these should ever be included by a driver, or a user's sketch.
36
+#include "settings.h"
37
+#include "printhex.h"
38
+#include "message.h"
39
+
40
+#include "hexdump.h"
41
+//#include "sink_parser.h"
42
+#include "max3421e.h"
43
+#include "address.h"
44
+//#include "avrpins.h"
45
+#include "usb_ch9.h"
46
+//#include "usbhost.h"
47
+#include "../usb_host.h"
48
+#include "UsbCore.h"
49
+#include "parsetools.h"
50
+#include "confdescparser.h"
51
+
52
+#endif //_usb_h_

+ 314
- 0
Marlin/src/sd/usb_flashdrive/lib/UsbCore.h 파일 보기

@@ -0,0 +1,314 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#ifndef _usb_h_
26
+  #error "Never include UsbCore.h directly; include Usb.h instead"
27
+#endif
28
+
29
+#ifndef USBCORE_H
30
+#define USBCORE_H
31
+
32
+// Not used anymore? If anyone uses this, please let us know so that this may be
33
+// moved to the proper place, settings.h.
34
+//#define USB_METHODS_INLINE
35
+
36
+/* shield pins. First parameter - SS pin, second parameter - INT pin */
37
+
38
+#ifdef __MARLIN_FIRMWARE__
39
+typedef MAX3421e MAX3421E; // Marlin redefines this class in "../usb_host.h"
40
+#elif defined(BOARD_BLACK_WIDDOW)
41
+typedef MAX3421e<P6, P3> MAX3421E; // Black Widow
42
+#elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
43
+#if EXT_RAM
44
+typedef MAX3421e<P20, P7> MAX3421E; // Teensy++ 2.0 with XMEM2
45
+#else
46
+typedef MAX3421e<P9, P8> MAX3421E; // Teensy++ 1.0 and 2.0
47
+#endif
48
+#elif defined(BOARD_MEGA_ADK)
49
+typedef MAX3421e<P53, P54> MAX3421E; // Arduino Mega ADK
50
+#elif defined(ARDUINO_AVR_BALANDUINO)
51
+typedef MAX3421e<P20, P19> MAX3421E; // Balanduino
52
+#elif defined(__ARDUINO_X86__) && PLATFORM_ID == 0x06
53
+typedef MAX3421e<P3, P2> MAX3421E; // The Intel Galileo supports much faster read and write speed at pin 2 and 3
54
+#elif defined(ESP8266)
55
+typedef MAX3421e<P15, P5> MAX3421E; // ESP8266 boards
56
+#elif defined(ESP32)
57
+typedef MAX3421e<P5, P17> MAX3421E; // ESP32 boards
58
+#else
59
+typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560, Leonardo, Due etc.), Intel Edison, Intel Galileo 2 or Teensy 2.0 and 3.x
60
+#endif
61
+
62
+/* Common setup data constant combinations  */
63
+#define bmREQ_GET_DESCR     USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE     //get descriptor request type
64
+#define bmREQ_SET           USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE     //set request type for all but 'set feature' and 'set interface'
65
+#define bmREQ_CL_GET_INTF   USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE     //get interface request type
66
+
67
+// D7           data transfer direction (0 - host-to-device, 1 - device-to-host)
68
+// D6-5         Type (0- standard, 1 - class, 2 - vendor, 3 - reserved)
69
+// D4-0         Recipient (0 - device, 1 - interface, 2 - endpoint, 3 - other, 4..31 - reserved)
70
+
71
+// USB Device Classes
72
+#define USB_CLASS_USE_CLASS_INFO        0x00    // Use Class Info in the Interface Descriptors
73
+#define USB_CLASS_AUDIO                 0x01    // Audio
74
+#define USB_CLASS_COM_AND_CDC_CTRL      0x02    // Communications and CDC Control
75
+#define USB_CLASS_HID                   0x03    // HID
76
+#define USB_CLASS_PHYSICAL              0x05    // Physical
77
+#define USB_CLASS_IMAGE                 0x06    // Image
78
+#define USB_CLASS_PRINTER               0x07    // Printer
79
+#define USB_CLASS_MASS_STORAGE          0x08    // Mass Storage
80
+#define USB_CLASS_HUB                   0x09    // Hub
81
+#define USB_CLASS_CDC_DATA              0x0a    // CDC-Data
82
+#define USB_CLASS_SMART_CARD            0x0b    // Smart-Card
83
+#define USB_CLASS_CONTENT_SECURITY      0x0d    // Content Security
84
+#define USB_CLASS_VIDEO                 0x0e    // Video
85
+#define USB_CLASS_PERSONAL_HEALTH       0x0f    // Personal Healthcare
86
+#define USB_CLASS_DIAGNOSTIC_DEVICE     0xdc    // Diagnostic Device
87
+#define USB_CLASS_WIRELESS_CTRL         0xe0    // Wireless Controller
88
+#define USB_CLASS_MISC                  0xef    // Miscellaneous
89
+#define USB_CLASS_APP_SPECIFIC          0xfe    // Application Specific
90
+#define USB_CLASS_VENDOR_SPECIFIC       0xff    // Vendor Specific
91
+
92
+// Additional Error Codes
93
+#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED       0xD1
94
+#define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE     0xD2
95
+#define USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS       0xD3
96
+#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL          0xD4
97
+#define USB_ERROR_HUB_ADDRESS_OVERFLOW                  0xD5
98
+#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL             0xD6
99
+#define USB_ERROR_EPINFO_IS_NULL                        0xD7
100
+#define USB_ERROR_INVALID_ARGUMENT                      0xD8
101
+#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE         0xD9
102
+#define USB_ERROR_INVALID_MAX_PKT_SIZE                  0xDA
103
+#define USB_ERROR_EP_NOT_FOUND_IN_TBL                   0xDB
104
+#define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET      0xE0
105
+#define USB_ERROR_FailGetDevDescr                       0xE1
106
+#define USB_ERROR_FailSetDevTblEntry                    0xE2
107
+#define USB_ERROR_FailGetConfDescr                      0xE3
108
+#define USB_ERROR_TRANSFER_TIMEOUT                      0xFF
109
+
110
+#define USB_XFER_TIMEOUT        5000    // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
111
+//#define USB_NAK_LIMIT         32000   // NAK limit for a transfer. 0 means NAKs are not counted
112
+#define USB_RETRY_LIMIT         3       // 3 retry limit for a transfer
113
+#define USB_SETTLE_DELAY        200     // settle delay in milliseconds
114
+
115
+#define USB_NUMDEVICES          16      //number of USB devices
116
+//#define HUB_MAX_HUBS          7       // maximum number of hubs that can be attached to the host controller
117
+#define HUB_PORT_RESET_DELAY    20      // hub port reset delay 10 ms recomended, can be up to 20 ms
118
+
119
+/* USB state machine states */
120
+#define USB_STATE_MASK                                      0xf0
121
+
122
+#define USB_STATE_DETACHED                                  0x10
123
+#define USB_DETACHED_SUBSTATE_INITIALIZE                    0x11
124
+#define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE               0x12
125
+#define USB_DETACHED_SUBSTATE_ILLEGAL                       0x13
126
+#define USB_ATTACHED_SUBSTATE_SETTLE                        0x20
127
+#define USB_ATTACHED_SUBSTATE_RESET_DEVICE                  0x30
128
+#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE           0x40
129
+#define USB_ATTACHED_SUBSTATE_WAIT_SOF                      0x50
130
+#define USB_ATTACHED_SUBSTATE_WAIT_RESET                    0x51
131
+#define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE    0x60
132
+#define USB_STATE_ADDRESSING                                0x70
133
+#define USB_STATE_CONFIGURING                               0x80
134
+#define USB_STATE_RUNNING                                   0x90
135
+#define USB_STATE_ERROR                                     0xa0
136
+
137
+class USBDeviceConfig {
138
+public:
139
+
140
+        virtual uint8_t Init(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed __attribute__((unused))) {
141
+                return 0;
142
+        }
143
+
144
+        virtual uint8_t ConfigureDevice(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed __attribute__((unused))) {
145
+                return 0;
146
+        }
147
+
148
+        virtual uint8_t Release() {
149
+                return 0;
150
+        }
151
+
152
+        virtual uint8_t Poll() {
153
+                return 0;
154
+        }
155
+
156
+        virtual uint8_t GetAddress() {
157
+                return 0;
158
+        }
159
+
160
+        virtual void ResetHubPort(uint8_t port __attribute__((unused))) {
161
+                return;
162
+        } // Note used for hubs only!
163
+
164
+        virtual bool VIDPIDOK(uint16_t vid __attribute__((unused)), uint16_t pid __attribute__((unused))) {
165
+                return false;
166
+        }
167
+
168
+        virtual bool DEVCLASSOK(uint8_t klass __attribute__((unused))) {
169
+                return false;
170
+        }
171
+
172
+        virtual bool DEVSUBCLASSOK(uint8_t subklass __attribute__((unused))) {
173
+                return true;
174
+        }
175
+
176
+};
177
+
178
+/* USB Setup Packet Structure   */
179
+typedef struct {
180
+
181
+        union { // offset   description
182
+                uint8_t bmRequestType; //   0      Bit-map of request type
183
+
184
+                struct {
185
+                        uint8_t recipient : 5; //          Recipient of the request
186
+                        uint8_t type : 2; //          Type of request
187
+                        uint8_t direction : 1; //          Direction of data X-fer
188
+                } __attribute__((packed));
189
+        } ReqType_u;
190
+        uint8_t bRequest; //   1      Request
191
+
192
+        union {
193
+                uint16_t wValue; //   2      Depends on bRequest
194
+
195
+                struct {
196
+                        uint8_t wValueLo;
197
+                        uint8_t wValueHi;
198
+                } __attribute__((packed));
199
+        } wVal_u;
200
+        uint16_t wIndex; //   4      Depends on bRequest
201
+        uint16_t wLength; //   6      Depends on bRequest
202
+} __attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
203
+
204
+
205
+
206
+// Base class for incoming data parser
207
+
208
+class USBReadParser {
209
+public:
210
+        virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) = 0;
211
+};
212
+
213
+class USB : public MAX3421E {
214
+        AddressPoolImpl<USB_NUMDEVICES> addrPool;
215
+        USBDeviceConfig* devConfig[USB_NUMDEVICES];
216
+        uint8_t bmHubPre;
217
+
218
+public:
219
+        USB(void);
220
+
221
+        void SetHubPreMask() {
222
+                bmHubPre |= bmHUBPRE;
223
+        };
224
+
225
+        void ResetHubPreMask() {
226
+                bmHubPre &= (~bmHUBPRE);
227
+        };
228
+
229
+        AddressPool& GetAddressPool() {
230
+                return (AddressPool&)addrPool;
231
+        };
232
+
233
+        uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
234
+                for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
235
+                        if(!devConfig[i]) {
236
+                                devConfig[i] = pdev;
237
+                                return 0;
238
+                        }
239
+                }
240
+                return USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS;
241
+        };
242
+
243
+        void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
244
+                addrPool.ForEachUsbDevice(pfunc);
245
+        };
246
+        uint8_t getUsbTaskState(void);
247
+        void setUsbTaskState(uint8_t state);
248
+
249
+        EpInfo* getEpInfoEntry(uint8_t addr, uint8_t ep);
250
+        uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr);
251
+
252
+        /* Control requests */
253
+        uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr);
254
+        uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr);
255
+
256
+        uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p);
257
+
258
+        uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
259
+        uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr);
260
+        uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value);
261
+        /**/
262
+        uint8_t ctrlData(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, bool direction);
263
+        uint8_t ctrlStatus(uint8_t ep, bool direction, uint16_t nak_limit);
264
+        uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval = 0);
265
+        uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data);
266
+        uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit);
267
+
268
+        void Task(void);
269
+
270
+        uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed);
271
+        uint8_t Configuring(uint8_t parent, uint8_t port, bool lowspeed);
272
+        uint8_t ReleaseDevice(uint8_t addr);
273
+
274
+        uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
275
+                uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p);
276
+
277
+private:
278
+        void init();
279
+        uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit);
280
+        uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data);
281
+        uint8_t InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval = 0);
282
+        uint8_t AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed);
283
+};
284
+
285
+#if 0 //defined(USB_METHODS_INLINE)
286
+//get device descriptor
287
+
288
+inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
289
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr));
290
+}
291
+//get configuration descriptor
292
+
293
+inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
294
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr));
295
+}
296
+//get string descriptor
297
+
298
+inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) {
299
+        return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr));
300
+}
301
+//set address
302
+
303
+inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
304
+        return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL));
305
+}
306
+//set configuration
307
+
308
+inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
309
+        return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL));
310
+}
311
+
312
+#endif // defined(USB_METHODS_INLINE)
313
+
314
+#endif /* USBCORE_H */

+ 290
- 0
Marlin/src/sd/usb_flashdrive/lib/address.h 파일 보기

@@ -0,0 +1,290 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#if !defined(_usb_h_) || defined(__ADDRESS_H__)
26
+#error "Never include address.h directly; include Usb.h instead"
27
+#else
28
+#define __ADDRESS_H__
29
+
30
+
31
+
32
+/* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
33
+/* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */
34
+#define USB_NAK_MAX_POWER               15              //NAK binary order maximum value
35
+#define USB_NAK_DEFAULT                 14              //default 32K-1 NAKs before giving up
36
+#define USB_NAK_NOWAIT                  1               //Single NAK stops transfer
37
+#define USB_NAK_NONAK                   0               //Do not count NAKs, stop retrying after USB Timeout
38
+
39
+struct EpInfo {
40
+        uint8_t epAddr; // Endpoint address
41
+        uint8_t maxPktSize; // Maximum packet size
42
+
43
+        union {
44
+                uint8_t epAttribs;
45
+
46
+                struct {
47
+                        uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
48
+                        uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
49
+                        uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
50
+                } __attribute__((packed));
51
+        };
52
+} __attribute__((packed));
53
+
54
+//        7   6   5   4   3   2   1   0
55
+//  ---------------------------------
56
+//  |   | H | P | P | P | A | A | A |
57
+//  ---------------------------------
58
+//
59
+// H - if 1 the address is a hub address
60
+// P - parent hub address
61
+// A - device address / port number in case of hub
62
+//
63
+
64
+struct UsbDeviceAddress {
65
+
66
+        union {
67
+
68
+                struct {
69
+                        uint8_t bmAddress : 3; // device address/port number
70
+                        uint8_t bmParent : 3; // parent hub address
71
+                        uint8_t bmHub : 1; // hub flag
72
+                        uint8_t bmReserved : 1; // reserved, must be zero
73
+                } __attribute__((packed));
74
+                uint8_t devAddress;
75
+        };
76
+} __attribute__((packed));
77
+
78
+#define bmUSB_DEV_ADDR_ADDRESS          0x07
79
+#define bmUSB_DEV_ADDR_PARENT           0x38
80
+#define bmUSB_DEV_ADDR_HUB              0x40
81
+
82
+struct UsbDevice {
83
+        EpInfo *epinfo; // endpoint info pointer
84
+        UsbDeviceAddress address;
85
+        uint8_t epcount; // number of endpoints
86
+        bool lowspeed; // indicates if a device is the low speed one
87
+        //      uint8_t devclass; // device class
88
+} __attribute__((packed));
89
+
90
+class AddressPool {
91
+public:
92
+        virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) = 0;
93
+        virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) = 0;
94
+        virtual void FreeAddress(uint8_t addr) = 0;
95
+};
96
+
97
+typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
98
+
99
+#define ADDR_ERROR_INVALID_INDEX                0xFF
100
+#define ADDR_ERROR_INVALID_ADDRESS              0xFF
101
+
102
+template <const uint8_t MAX_DEVICES_ALLOWED>
103
+class AddressPoolImpl : public AddressPool {
104
+        EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device
105
+
106
+        uint8_t hubCounter; // hub counter is kept
107
+        // in order to avoid hub address duplication
108
+
109
+        UsbDevice thePool[MAX_DEVICES_ALLOWED];
110
+
111
+        // Initializes address pool entry
112
+
113
+        void InitEntry(uint8_t index) {
114
+                thePool[index].address.devAddress = 0;
115
+                thePool[index].epcount = 1;
116
+                thePool[index].lowspeed = 0;
117
+                thePool[index].epinfo = &dev0ep;
118
+        };
119
+
120
+        // Returns thePool index for a given address
121
+
122
+        uint8_t FindAddressIndex(uint8_t address = 0) {
123
+                for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) {
124
+                        if(thePool[i].address.devAddress == address)
125
+                                return i;
126
+                }
127
+                return 0;
128
+        };
129
+
130
+        // Returns thePool child index for a given parent
131
+
132
+        uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) {
133
+                for(uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) {
134
+                        if(thePool[i].address.bmParent == addr.bmAddress)
135
+                                return i;
136
+                }
137
+                return 0;
138
+        };
139
+
140
+        // Frees address entry specified by index parameter
141
+
142
+        void FreeAddressByIndex(uint8_t index) {
143
+                // Zero field is reserved and should not be affected
144
+                if(index == 0)
145
+                        return;
146
+
147
+                UsbDeviceAddress uda = thePool[index].address;
148
+                // If a hub was switched off all port addresses should be freed
149
+                if(uda.bmHub == 1) {
150
+                        for(uint8_t i = 1; (i = FindChildIndex(uda, i));)
151
+                                FreeAddressByIndex(i);
152
+
153
+                        // If the hub had the last allocated address, hubCounter should be decremented
154
+                        if(hubCounter == uda.bmAddress)
155
+                                hubCounter--;
156
+                }
157
+                InitEntry(index);
158
+        }
159
+
160
+        // Initializes the whole address pool at once
161
+
162
+        void InitAllAddresses() {
163
+                for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
164
+                        InitEntry(i);
165
+
166
+                hubCounter = 0;
167
+        };
168
+
169
+public:
170
+
171
+        AddressPoolImpl() : hubCounter(0) {
172
+                // Zero address is reserved
173
+                InitEntry(0);
174
+
175
+                thePool[0].address.devAddress = 0;
176
+                thePool[0].epinfo = &dev0ep;
177
+                dev0ep.epAddr = 0;
178
+                dev0ep.maxPktSize = 8;
179
+                dev0ep.bmSndToggle = 0; // Set DATA0/1 toggles to 0
180
+                dev0ep.bmRcvToggle = 0;
181
+                dev0ep.bmNakPower = USB_NAK_MAX_POWER;
182
+
183
+                InitAllAddresses();
184
+        };
185
+
186
+        // Returns a pointer to a specified address entry
187
+
188
+        virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
189
+                if(!addr)
190
+                        return thePool;
191
+
192
+                uint8_t index = FindAddressIndex(addr);
193
+
194
+                return (!index) ? NULL : thePool + index;
195
+        };
196
+
197
+        // Performs an operation specified by pfunc for each addressed device
198
+
199
+        void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
200
+                if(!pfunc)
201
+                        return;
202
+
203
+                for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
204
+                        if(thePool[i].address.devAddress)
205
+                                pfunc(thePool + i);
206
+        };
207
+
208
+        // Allocates new address
209
+
210
+        virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) {
211
+                /* if (parent != 0 && port == 0)
212
+                        USB_HOST_SERIAL.println("PRT:0"); */
213
+                UsbDeviceAddress _parent;
214
+                _parent.devAddress = parent;
215
+                if(_parent.bmReserved || port > 7)
216
+                        //if(parent > 127 || port > 7)
217
+                        return 0;
218
+
219
+                if(is_hub && hubCounter == 7)
220
+                        return 0;
221
+
222
+                // finds first empty address entry starting from one
223
+                uint8_t index = FindAddressIndex(0);
224
+
225
+                if(!index) // if empty entry is not found
226
+                        return 0;
227
+
228
+                if(_parent.devAddress == 0) {
229
+                        if(is_hub) {
230
+                                thePool[index].address.devAddress = 0x41;
231
+                                hubCounter++;
232
+                        } else
233
+                                thePool[index].address.devAddress = 1;
234
+
235
+                        return thePool[index].address.devAddress;
236
+                }
237
+
238
+                UsbDeviceAddress addr;
239
+                addr.devAddress = 0; // Ensure all bits are zero
240
+                addr.bmParent = _parent.bmAddress;
241
+                if(is_hub) {
242
+                        addr.bmHub = 1;
243
+                        addr.bmAddress = ++hubCounter;
244
+                } else {
245
+                        addr.bmHub = 0;
246
+                        addr.bmAddress = port;
247
+                }
248
+                thePool[index].address = addr;
249
+                /*
250
+                                USB_HOST_SERIAL.print("Addr:");
251
+                                USB_HOST_SERIAL.print(addr.bmHub, HEX);
252
+                                USB_HOST_SERIAL.print(".");
253
+                                USB_HOST_SERIAL.print(addr.bmParent, HEX);
254
+                                USB_HOST_SERIAL.print(".");
255
+                                USB_HOST_SERIAL.println(addr.bmAddress, HEX);
256
+                 */
257
+                return thePool[index].address.devAddress;
258
+        };
259
+
260
+        // Empties pool entry
261
+
262
+        virtual void FreeAddress(uint8_t addr) {
263
+                // if the root hub is disconnected all the addresses should be initialized
264
+                if(addr == 0x41) {
265
+                        InitAllAddresses();
266
+                        return;
267
+                }
268
+                uint8_t index = FindAddressIndex(addr);
269
+                FreeAddressByIndex(index);
270
+        };
271
+
272
+        // Returns number of hubs attached
273
+        // It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
274
+        //uint8_t GetNumHubs()
275
+        //{
276
+        //        return hubCounter;
277
+        //};
278
+        //uint8_t GetNumDevices()
279
+        //{
280
+        //        uint8_t counter = 0;
281
+
282
+        //        for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
283
+        //                if (thePool[i].address != 0);
284
+        //                        counter ++;
285
+
286
+        //        return counter;
287
+        //};
288
+};
289
+
290
+#endif // __ADDRESS_H__

+ 217
- 0
Marlin/src/sd/usb_flashdrive/lib/confdescparser.h 파일 보기

@@ -0,0 +1,217 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+#if !defined(_usb_h_) || defined(__CONFDESCPARSER_H__)
25
+#error "Never include confdescparser.h directly; include Usb.h instead"
26
+#else
27
+
28
+#define __CONFDESCPARSER_H__
29
+
30
+class UsbConfigXtracter {
31
+public:
32
+        //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
33
+        //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
34
+
35
+        virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
36
+        };
37
+};
38
+
39
+#define CP_MASK_COMPARE_CLASS                   1
40
+#define CP_MASK_COMPARE_SUBCLASS                2
41
+#define CP_MASK_COMPARE_PROTOCOL                4
42
+#define CP_MASK_COMPARE_ALL                     7
43
+
44
+// Configuration Descriptor Parser Class Template
45
+
46
+template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
47
+class ConfigDescParser : public USBReadParser {
48
+        UsbConfigXtracter *theXtractor;
49
+        MultiValueBuffer theBuffer;
50
+        MultiByteValueParser valParser;
51
+        ByteSkipper theSkipper;
52
+        uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
53
+
54
+        uint8_t stateParseDescr; // ParseDescriptor state
55
+
56
+        uint8_t dscrLen; // Descriptor length
57
+        uint8_t dscrType; // Descriptor type
58
+
59
+        bool isGoodInterface; // Apropriate interface flag
60
+        uint8_t confValue; // Configuration value
61
+        uint8_t protoValue; // Protocol value
62
+        uint8_t ifaceNumber; // Interface number
63
+        uint8_t ifaceAltSet; // Interface alternate settings
64
+
65
+        bool UseOr;
66
+        bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
67
+        void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
68
+
69
+public:
70
+
71
+        void SetOR(void) {
72
+                UseOr = true;
73
+        }
74
+        ConfigDescParser(UsbConfigXtracter *xtractor);
75
+        void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
76
+};
77
+
78
+template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
79
+ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ConfigDescParser(UsbConfigXtracter *xtractor) :
80
+theXtractor(xtractor),
81
+stateParseDescr(0),
82
+dscrLen(0),
83
+dscrType(0),
84
+UseOr(false) {
85
+        theBuffer.pValue = varBuffer;
86
+        valParser.Initialize(&theBuffer);
87
+        theSkipper.Initialize(&theBuffer);
88
+};
89
+
90
+template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
91
+void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset __attribute__((unused))) {
92
+        uint16_t cntdn = (uint16_t)len;
93
+        uint8_t *p = (uint8_t*)pbuf;
94
+
95
+        while(cntdn)
96
+                if(!ParseDescriptor(&p, &cntdn))
97
+                        return;
98
+}
99
+
100
+/* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and
101
+  compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
102
+template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
103
+bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
104
+        USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
105
+        USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
106
+        switch(stateParseDescr) {
107
+                case 0:
108
+                        theBuffer.valueSize = 2;
109
+                        valParser.Initialize(&theBuffer);
110
+                        stateParseDescr = 1;
111
+                case 1:
112
+                        if(!valParser.Parse(pp, pcntdn))
113
+                                return false;
114
+                        dscrLen = *((uint8_t*)theBuffer.pValue);
115
+                        dscrType = *((uint8_t*)theBuffer.pValue + 1);
116
+                        stateParseDescr = 2;
117
+                case 2:
118
+                        // This is a sort of hack. Assuming that two bytes are all ready in the buffer
119
+                        //      the pointer is positioned two bytes ahead in order for the rest of descriptor
120
+                        //      to be read right after the size and the type fields.
121
+                        // This should be used carefully. varBuffer should be used directly to handle data
122
+                        //      in the buffer.
123
+                        theBuffer.pValue = varBuffer + 2;
124
+                        stateParseDescr = 3;
125
+                case 3:
126
+                        switch(dscrType) {
127
+                                case USB_DESCRIPTOR_INTERFACE:
128
+                                        isGoodInterface = false;
129
+                                        break;
130
+                                case USB_DESCRIPTOR_CONFIGURATION:
131
+                                case USB_DESCRIPTOR_ENDPOINT:
132
+                                case HID_DESCRIPTOR_HID:
133
+                                        break;
134
+                        }
135
+                        theBuffer.valueSize = dscrLen - 2;
136
+                        valParser.Initialize(&theBuffer);
137
+                        stateParseDescr = 4;
138
+                case 4:
139
+                        switch(dscrType) {
140
+                                case USB_DESCRIPTOR_CONFIGURATION:
141
+                                        if(!valParser.Parse(pp, pcntdn))
142
+                                                return false;
143
+                                        confValue = ucd->bConfigurationValue;
144
+                                        break;
145
+                                case USB_DESCRIPTOR_INTERFACE:
146
+                                        if(!valParser.Parse(pp, pcntdn))
147
+                                                return false;
148
+                                        if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID)
149
+                                                break;
150
+                                        if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID)
151
+                                                break;
152
+                                        if(UseOr) {
153
+                                                if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol)))
154
+                                                        break;
155
+                                        } else {
156
+                                                if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID)
157
+                                                        break;
158
+                                        }
159
+                                        isGoodInterface = true;
160
+                                        ifaceNumber = uid->bInterfaceNumber;
161
+                                        ifaceAltSet = uid->bAlternateSetting;
162
+                                        protoValue = uid->bInterfaceProtocol;
163
+                                        break;
164
+                                case USB_DESCRIPTOR_ENDPOINT:
165
+                                        if(!valParser.Parse(pp, pcntdn))
166
+                                                return false;
167
+                                        if(isGoodInterface)
168
+                                                if(theXtractor)
169
+                                                        theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
170
+                                        break;
171
+                                        //case HID_DESCRIPTOR_HID:
172
+                                        //      if (!valParser.Parse(pp, pcntdn))
173
+                                        //              return false;
174
+                                        //      PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
175
+                                        //      break;
176
+                                default:
177
+                                        if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
178
+                                                return false;
179
+                        }
180
+                        theBuffer.pValue = varBuffer;
181
+                        stateParseDescr = 0;
182
+        }
183
+        return true;
184
+}
185
+
186
+template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
187
+void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc) {
188
+        Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
189
+        Notify(PSTR("bDescLength:\t\t"), 0x80);
190
+        PrintHex<uint8_t > (pDesc->bLength, 0x80);
191
+
192
+        Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
193
+        PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
194
+
195
+        Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
196
+        PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
197
+
198
+        Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
199
+        PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
200
+
201
+        Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
202
+        PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80);
203
+
204
+        for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) {
205
+                HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType);
206
+
207
+                Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);
208
+                PrintHex<uint8_t > (pLT[i].bDescrType, 0x80);
209
+
210
+                Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
211
+                PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
212
+        }
213
+        Notify(PSTR("\r\n"), 0x80);
214
+}
215
+
216
+
217
+#endif // __CONFDESCPARSER_H__

+ 69
- 0
Marlin/src/sd/usb_flashdrive/lib/hexdump.h 파일 보기

@@ -0,0 +1,69 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#if !defined(_usb_h_) || defined(__HEXDUMP_H__)
26
+#error "Never include hexdump.h directly; include Usb.h instead"
27
+#else
28
+#define __HEXDUMP_H__
29
+
30
+extern int UsbDEBUGlvl;
31
+
32
+template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
33
+class HexDumper : public BASE_CLASS {
34
+        uint8_t byteCount;
35
+        OFFSET_TYPE byteTotal;
36
+
37
+public:
38
+
39
+        HexDumper() : byteCount(0), byteTotal(0) {
40
+        };
41
+
42
+        void Initialize() {
43
+                byteCount = 0;
44
+                byteTotal = 0;
45
+        };
46
+
47
+        void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset);
48
+};
49
+
50
+template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
51
+void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset __attribute__((unused))) {
52
+        if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
53
+                for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
54
+                        if(!byteCount) {
55
+                                PrintHex<OFFSET_TYPE > (byteTotal, 0x80);
56
+                                E_Notify(PSTR(": "), 0x80);
57
+                        }
58
+                        PrintHex<uint8_t > (pbuf[j], 0x80);
59
+                        E_Notify(PSTR(" "), 0x80);
60
+
61
+                        if(byteCount == 15) {
62
+                                E_Notify(PSTR("\r\n"), 0x80);
63
+                                byteCount = 0xFF;
64
+                        }
65
+                }
66
+        }
67
+}
68
+
69
+#endif // __HEXDUMP_H__

+ 89
- 0
Marlin/src/sd/usb_flashdrive/lib/macros.h 파일 보기

@@ -0,0 +1,89 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#ifndef _usb_h_
26
+  #error "Never include macros.h directly; include Usb.h instead"
27
+#endif
28
+
29
+#ifndef MACROS_H
30
+#define MACROS_H
31
+
32
+////////////////////////////////////////////////////////////////////////////////
33
+// HANDY MACROS
34
+////////////////////////////////////////////////////////////////////////////////
35
+
36
+#define VALUE_BETWEEN(v,l,h) (((v)>(l)) && ((v)<(h)))
37
+#define VALUE_WITHIN(v,l,h) (((v)>=(l)) && ((v)<=(h)))
38
+#define output_pgm_message(wa,fp,mp,el) wa = &mp, fp((char *)pgm_read_pointer(wa), el)
39
+#define output_if_between(v,l,h,wa,fp,mp,el) if(VALUE_BETWEEN(v,l,h)) output_pgm_message(wa,fp,mp[v-(l+1)],el);
40
+
41
+#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
42
+#ifndef __BYTE_GRABBING_DEFINED__
43
+#define __BYTE_GRABBING_DEFINED__ 1
44
+#ifdef BROKEN_OPTIMIZER_LITTLE_ENDIAN
45
+// Note: Use this if your compiler generates horrible assembler!
46
+#define BGRAB0(__usi__)  (((uint8_t *)&(__usi__))[0])
47
+#define BGRAB1(__usi__)  (((uint8_t *)&(__usi__))[1])
48
+#define BGRAB2(__usi__)  (((uint8_t *)&(__usi__))[2])
49
+#define BGRAB3(__usi__)  (((uint8_t *)&(__usi__))[3])
50
+#define BGRAB4(__usi__)  (((uint8_t *)&(__usi__))[4])
51
+#define BGRAB5(__usi__)  (((uint8_t *)&(__usi__))[5])
52
+#define BGRAB6(__usi__)  (((uint8_t *)&(__usi__))[6])
53
+#define BGRAB7(__usi__)  (((uint8_t *)&(__usi__))[7])
54
+#else
55
+// Note: The cast alone to uint8_t is actually enough.
56
+// GCC throws out the "& 0xff", and the size is no different.
57
+// Some compilers need it.
58
+#define BGRAB0(__usi__)  ((uint8_t)((__usi__) & 0xff ))
59
+#define BGRAB1(__usi__)  ((uint8_t)(((__usi__) >> 8) & 0xff))
60
+#define BGRAB2(__usi__)  ((uint8_t)(((__usi__) >> 16) & 0xff))
61
+#define BGRAB3(__usi__)  ((uint8_t)(((__usi__) >> 24) & 0xff))
62
+#define BGRAB4(__usi__)  ((uint8_t)(((__usi__) >> 32) & 0xff))
63
+#define BGRAB5(__usi__)  ((uint8_t)(((__usi__) >> 40) & 0xff))
64
+#define BGRAB6(__usi__)  ((uint8_t)(((__usi__) >> 48) & 0xff))
65
+#define BGRAB7(__usi__)  ((uint8_t)(((__usi__) >> 56) & 0xff))
66
+#endif
67
+#define BOVER1(__usi__)  ((uint16_t)(__usi__) << 8)
68
+#define BOVER2(__usi__)  ((uint32_t)(__usi__) << 16)
69
+#define BOVER3(__usi__)  ((uint32_t)(__usi__) << 24)
70
+#define BOVER4(__usi__)  ((uint64_t)(__usi__) << 32)
71
+#define BOVER5(__usi__)  ((uint64_t)(__usi__) << 40)
72
+#define BOVER6(__usi__)  ((uint64_t)(__usi__) << 48)
73
+#define BOVER7(__usi__)  ((uint64_t)(__usi__) << 56)
74
+
75
+// These are the smallest and fastest ways I have found so far in pure C/C++.
76
+#define BMAKE16(__usc1__,__usc0__) ((uint16_t)((uint16_t)(__usc0__) | (uint16_t)BOVER1(__usc1__)))
77
+#define BMAKE32(__usc3__,__usc2__,__usc1__,__usc0__) ((uint32_t)((uint32_t)(__usc0__) | (uint32_t)BOVER1(__usc1__) | (uint32_t)BOVER2(__usc2__) | (uint32_t)BOVER3(__usc3__)))
78
+#define BMAKE64(__usc7__,__usc6__,__usc5__,__usc4__,__usc3__,__usc2__,__usc1__,__usc0__) ((uint64_t)((uint64_t)__usc0__ | (uint64_t)BOVER1(__usc1__) | (uint64_t)BOVER2(__usc2__) | (uint64_t)BOVER3(__usc3__) | (uint64_t)BOVER4(__usc4__) | (uint64_t)BOVER5(__usc5__) | (uint64_t)BOVER6(__usc6__) | (uint64_t)BOVER1(__usc7__)))
79
+#endif
80
+
81
+/*
82
+ * Debug macros: Strings are stored in progmem (flash) instead of RAM.
83
+ */
84
+#define USBTRACE(s) (Notify(PSTR(s), 0x80))
85
+#define USBTRACE1(s,l) (Notify(PSTR(s), l))
86
+#define USBTRACE2(s,r) (Notify(PSTR(s), 0x80), D_PrintHex((r), 0x80), Notify(PSTR("\r\n"), 0x80))
87
+#define USBTRACE3(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l), Notify(PSTR("\r\n"), l))
88
+
89
+#endif /* MACROS_H */

+ 1282
- 0
Marlin/src/sd/usb_flashdrive/lib/masstorage.cpp
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 578
- 0
Marlin/src/sd/usb_flashdrive/lib/masstorage.h 파일 보기

@@ -0,0 +1,578 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#if !defined(__MASSTORAGE_H__)
26
+#define __MASSTORAGE_H__
27
+
28
+// Cruft removal, makes driver smaller, faster.
29
+#ifndef MS_WANT_PARSER
30
+#define MS_WANT_PARSER 0
31
+#endif
32
+
33
+#include "Usb.h"
34
+
35
+#define bmREQ_MASSOUT       USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
36
+#define bmREQ_MASSIN        USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
37
+
38
+// Mass Storage Subclass Constants
39
+#define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00    // De facto use
40
+#define MASS_SUBCLASS_RBC               0x01
41
+#define MASS_SUBCLASS_ATAPI             0x02    // MMC-5 (ATAPI)
42
+#define MASS_SUBCLASS_OBSOLETE1         0x03    // Was QIC-157
43
+#define MASS_SUBCLASS_UFI               0x04    // Specifies how to interface Floppy Disk Drives to USB
44
+#define MASS_SUBCLASS_OBSOLETE2         0x05    // Was SFF-8070i
45
+#define MASS_SUBCLASS_SCSI              0x06    // SCSI Transparent Command Set
46
+#define MASS_SUBCLASS_LSDFS             0x07    // Specifies how host has to negotiate access before trying SCSI
47
+#define MASS_SUBCLASS_IEEE1667          0x08
48
+
49
+// Mass Storage Class Protocols
50
+#define MASS_PROTO_CBI                  0x00    // CBI (with command completion interrupt)
51
+#define MASS_PROTO_CBI_NO_INT           0x01    // CBI (without command completion interrupt)
52
+#define MASS_PROTO_OBSOLETE             0x02
53
+#define MASS_PROTO_BBB                  0x50    // Bulk Only Transport
54
+#define MASS_PROTO_UAS                  0x62
55
+
56
+// Request Codes
57
+#define MASS_REQ_ADSC                   0x00
58
+#define MASS_REQ_GET                    0xFC
59
+#define MASS_REQ_PUT                    0xFD
60
+#define MASS_REQ_GET_MAX_LUN            0xFE
61
+#define MASS_REQ_BOMSR                  0xFF    // Bulk-Only Mass Storage Reset
62
+
63
+#define MASS_CBW_SIGNATURE              0x43425355
64
+#define MASS_CSW_SIGNATURE              0x53425355
65
+
66
+#define MASS_CMD_DIR_OUT                0 // (0 << 7)
67
+#define MASS_CMD_DIR_IN                 0x80 //(1 << 7)
68
+
69
+/*
70
+ * Reference documents from T10 (http://www.t10.org)
71
+ * SCSI Primary Commands - 3 (SPC-3)
72
+ * SCSI Block Commands - 2 (SBC-2)
73
+ * Multi-Media Commands - 5 (MMC-5)
74
+ */
75
+
76
+/* Group 1 commands (CDB's here are should all be 6-bytes) */
77
+#define SCSI_CMD_TEST_UNIT_READY        0x00
78
+#define SCSI_CMD_REQUEST_SENSE          0x03
79
+#define SCSI_CMD_FORMAT_UNIT            0x04
80
+#define SCSI_CMD_READ_6                 0x08
81
+#define SCSI_CMD_WRITE_6                0x0A
82
+#define SCSI_CMD_INQUIRY                0x12
83
+#define SCSI_CMD_MODE_SELECT_6          0x15
84
+#define SCSI_CMD_MODE_SENSE_6           0x1A
85
+#define SCSI_CMD_START_STOP_UNIT        0x1B
86
+#define SCSI_CMD_PREVENT_REMOVAL        0x1E
87
+/* Group 2 Commands (CDB's here are 10-bytes) */
88
+#define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23
89
+#define SCSI_CMD_READ_CAPACITY_10       0x25
90
+#define SCSI_CMD_READ_10                0x28
91
+#define SCSI_CMD_WRITE_10               0x2A
92
+#define SCSI_CMD_SEEK_10                0x2B
93
+#define SCSI_CMD_ERASE_10               0x2C
94
+#define SCSI_CMD_WRITE_AND_VERIFY_10    0x2E
95
+#define SCSI_CMD_VERIFY_10              0x2F
96
+#define SCSI_CMD_SYNCHRONIZE_CACHE      0x35
97
+#define SCSI_CMD_WRITE_BUFFER           0x3B
98
+#define SCSI_CMD_READ_BUFFER            0x3C
99
+#define SCSI_CMD_READ_SUBCHANNEL        0x42
100
+#define SCSI_CMD_READ_TOC               0x43
101
+#define SCSI_CMD_READ_HEADER            0x44
102
+#define SCSI_CMD_PLAY_AUDIO_10          0x45
103
+#define SCSI_CMD_GET_CONFIGURATION      0x46
104
+#define SCSI_CMD_PLAY_AUDIO_MSF         0x47
105
+#define SCSI_CMD_PLAY_AUDIO_TI          0x48
106
+#define SCSI_CMD_PLAY_TRACK_REL_10      0x49
107
+#define SCSI_CMD_GET_EVENT_STATUS       0x4A
108
+#define SCSI_CMD_PAUSE_RESUME           0x4B
109
+#define SCSI_CMD_READ_DISC_INFORMATION  0x51
110
+#define SCSI_CMD_READ_TRACK_INFORMATION 0x52
111
+#define SCSI_CMD_RESERVE_TRACK          0x53
112
+#define SCSI_CMD_SEND_OPC_INFORMATION   0x54
113
+#define SCSI_CMD_MODE_SELECT_10         0x55
114
+#define SCSI_CMD_REPAIR_TRACK           0x58
115
+#define SCSI_CMD_MODE_SENSE_10          0x5A
116
+#define SCSI_CMD_CLOSE_TRACK_SESSION    0x5B
117
+#define SCSI_CMD_READ_BUFFER_CAPACITY   0x5C
118
+#define SCSI_CMD_SEND_CUE_SHEET         0x5D
119
+/* Group 5 Commands (CDB's here are 12-bytes) */
120
+#define SCSI_CMD_REPORT_LUNS            0xA0
121
+#define SCSI_CMD_BLANK                  0xA1
122
+#define SCSI_CMD_SECURITY_PROTOCOL_IN   0xA2
123
+#define SCSI_CMD_SEND_KEY               0xA3
124
+#define SCSI_CMD_REPORT_KEY             0xA4
125
+#define SCSI_CMD_PLAY_AUDIO_12          0xA5
126
+#define SCSI_CMD_LOAD_UNLOAD            0xA6
127
+#define SCSI_CMD_SET_READ_AHEAD         0xA7
128
+#define SCSI_CMD_READ_12                0xA8
129
+#define SCSI_CMD_PLAY_TRACK_REL_12      0xA9
130
+#define SCSI_CMD_WRITE_12               0xAA
131
+#define SCSI_CMD_READ_MEDIA_SERIAL_12   0xAB
132
+#define SCSI_CMD_GET_PERFORMANCE        0xAC
133
+#define SCSI_CMD_READ_DVD_STRUCTURE     0xAD
134
+#define SCSI_CMD_SECURITY_PROTOCOL_OUT  0xB5
135
+#define SCSI_CMD_SET_STREAMING          0xB6
136
+#define SCSI_CMD_READ_MSF               0xB9
137
+#define SCSI_CMD_SET_SPEED              0xBB
138
+#define SCSI_CMD_MECHANISM_STATUS       0xBD
139
+#define SCSI_CMD_READ_CD                0xBE
140
+#define SCSI_CMD_SEND_DISC_STRUCTURE    0xBF
141
+/* Vendor-unique Commands, included for completeness */
142
+#define SCSI_CMD_CD_PLAYBACK_STATUS     0xC4 /* SONY unique */
143
+#define SCSI_CMD_PLAYBACK_CONTROL       0xC9 /* SONY unique */
144
+#define SCSI_CMD_READ_CDDA              0xD8 /* Vendor unique */
145
+#define SCSI_CMD_READ_CDXA              0xDB /* Vendor unique */
146
+#define SCSI_CMD_READ_ALL_SUBCODES      0xDF /* Vendor unique */
147
+
148
+/* SCSI error codes */
149
+#define SCSI_S_NOT_READY                0x02
150
+#define SCSI_S_MEDIUM_ERROR             0x03
151
+#define SCSI_S_ILLEGAL_REQUEST          0x05
152
+#define SCSI_S_UNIT_ATTENTION           0x06
153
+#define SCSI_ASC_LBA_OUT_OF_RANGE       0x21
154
+#define SCSI_ASC_MEDIA_CHANGED          0x28
155
+#define SCSI_ASC_MEDIUM_NOT_PRESENT     0x3A
156
+
157
+/* USB error codes */
158
+#define MASS_ERR_SUCCESS                0x00
159
+#define MASS_ERR_PHASE_ERROR            0x02
160
+#define MASS_ERR_UNIT_NOT_READY         0x03
161
+#define MASS_ERR_UNIT_BUSY              0x04
162
+#define MASS_ERR_STALL                  0x05
163
+#define MASS_ERR_CMD_NOT_SUPPORTED      0x06
164
+#define MASS_ERR_INVALID_CSW            0x07
165
+#define MASS_ERR_NO_MEDIA               0x08
166
+#define MASS_ERR_BAD_LBA                0x09
167
+#define MASS_ERR_MEDIA_CHANGED          0x0A
168
+#define MASS_ERR_DEVICE_DISCONNECTED    0x11
169
+#define MASS_ERR_UNABLE_TO_RECOVER      0x12    // Reset recovery error
170
+#define MASS_ERR_INVALID_LUN            0x13
171
+#define MASS_ERR_WRITE_STALL            0x14
172
+#define MASS_ERR_READ_NAKS              0x15
173
+#define MASS_ERR_WRITE_NAKS             0x16
174
+#define MASS_ERR_WRITE_PROTECTED        0x17
175
+#define MASS_ERR_NOT_IMPLEMENTED        0xFD
176
+#define MASS_ERR_GENERAL_SCSI_ERROR     0xFE
177
+#define MASS_ERR_GENERAL_USB_ERROR      0xFF
178
+#define MASS_ERR_USER                   0xA0    // For subclasses to define their own error codes
179
+
180
+#define MASS_TRANS_FLG_CALLBACK         0x01    // Callback is involved
181
+#define MASS_TRANS_FLG_NO_STALL_CHECK   0x02    // STALL condition is not checked
182
+#define MASS_TRANS_FLG_NO_PHASE_CHECK   0x04    // PHASE_ERROR is not checked
183
+
184
+#define MASS_MAX_ENDPOINTS              3
185
+
186
+struct Capacity {
187
+        uint8_t data[8];
188
+        //uint32_t dwBlockAddress;
189
+        //uint32_t dwBlockLength;
190
+} __attribute__((packed));
191
+
192
+struct BASICCDB {
193
+        uint8_t Opcode;
194
+
195
+        unsigned unused : 5;
196
+        unsigned LUN : 3;
197
+
198
+        uint8_t info[12];
199
+} __attribute__((packed));
200
+
201
+typedef BASICCDB BASICCDB_t;
202
+
203
+struct CDB6 {
204
+        uint8_t Opcode;
205
+
206
+        unsigned LBAMSB : 5;
207
+        unsigned LUN : 3;
208
+
209
+        uint8_t LBAHB;
210
+        uint8_t LBALB;
211
+        uint8_t AllocationLength;
212
+        uint8_t Control;
213
+
214
+public:
215
+
216
+        CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
217
+        Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
218
+        AllocationLength(_AllocationLength), Control(_Control) {
219
+        }
220
+
221
+        CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
222
+        Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0),
223
+        AllocationLength(_AllocationLength), Control(_Control) {
224
+        }
225
+} __attribute__((packed));
226
+
227
+typedef CDB6 CDB6_t;
228
+
229
+struct CDB10 {
230
+        uint8_t Opcode;
231
+
232
+        unsigned Service_Action : 5;
233
+        unsigned LUN : 3;
234
+
235
+        uint8_t LBA_L_M_MB;
236
+        uint8_t LBA_L_M_LB;
237
+        uint8_t LBA_L_L_MB;
238
+        uint8_t LBA_L_L_LB;
239
+
240
+        uint8_t Misc2;
241
+
242
+        uint8_t ALC_MB;
243
+        uint8_t ALC_LB;
244
+
245
+        uint8_t Control;
246
+public:
247
+
248
+        CDB10(uint8_t _Opcode, uint8_t _LUN) :
249
+        Opcode(_Opcode), Service_Action(0), LUN(_LUN),
250
+        LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
251
+        Misc2(0), ALC_MB(0), ALC_LB(0), Control(0) {
252
+        }
253
+
254
+        CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
255
+        Opcode(_Opcode), Service_Action(0), LUN(_LUN),
256
+        LBA_L_M_MB(BGRAB3(_LBA)), LBA_L_M_LB(BGRAB2(_LBA)), LBA_L_L_MB(BGRAB1(_LBA)), LBA_L_L_LB(BGRAB0(_LBA)),
257
+        Misc2(0), ALC_MB(BGRAB1(xflen)), ALC_LB(BGRAB0(xflen)), Control(0) {
258
+        }
259
+} __attribute__((packed));
260
+
261
+typedef CDB10 CDB10_t;
262
+
263
+struct CDB12 {
264
+        uint8_t Opcode;
265
+
266
+        unsigned Service_Action : 5;
267
+        unsigned Misc : 3;
268
+
269
+        uint8_t LBA_L_M_LB;
270
+        uint8_t LBA_L_L_MB;
271
+        uint8_t LBA_L_L_LB;
272
+
273
+        uint8_t ALC_M_LB;
274
+        uint8_t ALC_L_MB;
275
+        uint8_t ALC_L_LB;
276
+        uint8_t Control;
277
+} __attribute__((packed));
278
+
279
+typedef CDB12 CDB12_t;
280
+
281
+struct CDB_LBA32_16 {
282
+        uint8_t Opcode;
283
+
284
+        unsigned Service_Action : 5;
285
+        unsigned Misc : 3;
286
+
287
+        uint8_t LBA_L_M_MB;
288
+        uint8_t LBA_L_M_LB;
289
+        uint8_t LBA_L_L_MB;
290
+        uint8_t LBA_L_L_LB;
291
+
292
+        uint8_t A_M_M_MB;
293
+        uint8_t A_M_M_LB;
294
+        uint8_t A_M_L_MB;
295
+        uint8_t A_M_L_LB;
296
+
297
+        uint8_t ALC_M_MB;
298
+        uint8_t ALC_M_LB;
299
+        uint8_t ALC_L_MB;
300
+        uint8_t ALC_L_LB;
301
+
302
+        uint8_t Misc2;
303
+        uint8_t Control;
304
+} __attribute__((packed));
305
+
306
+struct CDB_LBA64_16 {
307
+        uint8_t Opcode;
308
+        uint8_t Misc;
309
+
310
+        uint8_t LBA_M_M_MB;
311
+        uint8_t LBA_M_M_LB;
312
+        uint8_t LBA_M_L_MB;
313
+        uint8_t LBA_M_L_LB;
314
+
315
+        uint8_t LBA_L_M_MB;
316
+        uint8_t LBA_L_M_LB;
317
+        uint8_t LBA_L_L_MB;
318
+        uint8_t LBA_L_L_LB;
319
+
320
+        uint8_t ALC_M_MB;
321
+        uint8_t ALC_M_LB;
322
+        uint8_t ALC_L_MB;
323
+        uint8_t ALC_L_LB;
324
+
325
+        uint8_t Misc2;
326
+        uint8_t Control;
327
+} __attribute__((packed));
328
+
329
+struct InquiryResponse {
330
+        uint8_t DeviceType : 5;
331
+        uint8_t PeripheralQualifier : 3;
332
+
333
+        unsigned Reserved : 7;
334
+        unsigned Removable : 1;
335
+
336
+        uint8_t Version;
337
+
338
+        unsigned ResponseDataFormat : 4;
339
+        unsigned HISUP : 1;
340
+        unsigned NormACA : 1;
341
+        unsigned TrmTsk : 1;
342
+        unsigned AERC : 1;
343
+
344
+        uint8_t AdditionalLength;
345
+        //uint8_t Reserved3[2];
346
+
347
+        unsigned PROTECT : 1;
348
+        unsigned Res : 2;
349
+        unsigned ThreePC : 1;
350
+        unsigned TPGS : 2;
351
+        unsigned ACC : 1;
352
+        unsigned SCCS : 1;
353
+
354
+        unsigned ADDR16 : 1;
355
+        unsigned R1 : 1;
356
+        unsigned R2 : 1;
357
+        unsigned MCHNGR : 1;
358
+        unsigned MULTIP : 1;
359
+        unsigned VS : 1;
360
+        unsigned ENCSERV : 1;
361
+        unsigned BQUE : 1;
362
+
363
+        unsigned SoftReset : 1;
364
+        unsigned CmdQue : 1;
365
+        unsigned Reserved4 : 1;
366
+        unsigned Linked : 1;
367
+        unsigned Sync : 1;
368
+        unsigned WideBus16Bit : 1;
369
+        unsigned WideBus32Bit : 1;
370
+        unsigned RelAddr : 1;
371
+
372
+        uint8_t VendorID[8];
373
+        uint8_t ProductID[16];
374
+        uint8_t RevisionID[4];
375
+} __attribute__((packed));
376
+
377
+struct CommandBlockWrapperBase {
378
+        uint32_t dCBWSignature;
379
+        uint32_t dCBWTag;
380
+        uint32_t dCBWDataTransferLength;
381
+        uint8_t bmCBWFlags;
382
+public:
383
+
384
+        CommandBlockWrapperBase() {
385
+        }
386
+
387
+        CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs) :
388
+        dCBWSignature(MASS_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
389
+        }
390
+} __attribute__((packed));
391
+
392
+struct CommandBlockWrapper : public CommandBlockWrapperBase {
393
+
394
+        struct {
395
+                uint8_t bmCBWLUN : 4;
396
+                uint8_t bmReserved1 : 4;
397
+        };
398
+
399
+        struct {
400
+                uint8_t bmCBWCBLength : 4;
401
+                uint8_t bmReserved2 : 4;
402
+        };
403
+
404
+        uint8_t CBWCB[16];
405
+
406
+public:
407
+        // All zeroed.
408
+
409
+        CommandBlockWrapper() :
410
+        CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) {
411
+                for(int i = 0; i < 16; i++) CBWCB[i] = 0;
412
+        }
413
+
414
+        // Generic Wrap, CDB zeroed.
415
+
416
+        CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
417
+        CommandBlockWrapperBase(tag, xflen, flgs),
418
+        bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
419
+                for(int i = 0; i < 16; i++) CBWCB[i] = 0;
420
+                // Type punning can cause optimization problems and bugs.
421
+                // Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
422
+                //(((BASICCDB_t *) CBWCB)->LUN) = cmd;
423
+                BASICCDB_t *x = reinterpret_cast<BASICCDB_t *>(CBWCB);
424
+                x->LUN = cmd;
425
+        }
426
+
427
+        // Wrap for CDB of 6
428
+
429
+        CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
430
+        CommandBlockWrapperBase(tag, xflen, dir),
431
+        bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
432
+                memcpy(&CBWCB, cdb, 6);
433
+        }
434
+        // Wrap for CDB of 10
435
+
436
+        CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
437
+        CommandBlockWrapperBase(tag, xflen, dir),
438
+        bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
439
+                memcpy(&CBWCB, cdb, 10);
440
+        }
441
+} __attribute__((packed));
442
+
443
+struct CommandStatusWrapper {
444
+        uint32_t dCSWSignature;
445
+        uint32_t dCSWTag;
446
+        uint32_t dCSWDataResidue;
447
+        uint8_t bCSWStatus;
448
+} __attribute__((packed));
449
+
450
+struct RequestSenseResponce {
451
+        uint8_t bResponseCode;
452
+        uint8_t bSegmentNumber;
453
+
454
+        uint8_t bmSenseKey : 4;
455
+        uint8_t bmReserved : 1;
456
+        uint8_t bmILI : 1;
457
+        uint8_t bmEOM : 1;
458
+        uint8_t bmFileMark : 1;
459
+
460
+        uint8_t Information[4];
461
+        uint8_t bAdditionalLength;
462
+        uint8_t CmdSpecificInformation[4];
463
+        uint8_t bAdditionalSenseCode;
464
+        uint8_t bAdditionalSenseQualifier;
465
+        uint8_t bFieldReplaceableUnitCode;
466
+        uint8_t SenseKeySpecific[3];
467
+} __attribute__((packed));
468
+
469
+class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter {
470
+protected:
471
+        static const uint8_t epDataInIndex; // DataIn endpoint index
472
+        static const uint8_t epDataOutIndex; // DataOUT endpoint index
473
+        static const uint8_t epInterruptInIndex; // InterruptIN  endpoint index
474
+
475
+        USB *pUsb;
476
+        uint8_t bAddress;
477
+        uint8_t bConfNum; // configuration number
478
+        uint8_t bIface; // interface value
479
+        uint8_t bNumEP; // total number of EP in the configuration
480
+        uint32_t qNextPollTime; // next poll time
481
+        bool bPollEnable; // poll enable flag
482
+
483
+        EpInfo epInfo[MASS_MAX_ENDPOINTS];
484
+
485
+        uint32_t dCBWTag; // Tag
486
+        //uint32_t dCBWDataTransferLength; // Data Transfer Length
487
+        uint8_t bLastUsbError; // Last USB error
488
+        uint8_t bMaxLUN; // Max LUN
489
+        uint8_t bTheLUN; // Active LUN
490
+        uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
491
+        uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
492
+        bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
493
+        bool WriteOk[MASS_MAX_SUPPORTED_LUN];
494
+        void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
495
+
496
+
497
+        // Additional Initialization Method for Subclasses
498
+
499
+        virtual uint8_t OnInit() {
500
+                return 0;
501
+        };
502
+public:
503
+        BulkOnly(USB *p);
504
+
505
+        uint8_t GetLastUsbError() {
506
+                return bLastUsbError;
507
+        };
508
+
509
+        uint8_t GetbMaxLUN() {
510
+                return bMaxLUN; // Max LUN
511
+        }
512
+
513
+        uint8_t GetbTheLUN() {
514
+                return bTheLUN; // Active LUN
515
+        }
516
+
517
+        bool WriteProtected(uint8_t lun);
518
+        uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
519
+        uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
520
+        uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser *prs);
521
+        uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf);
522
+        uint8_t LockMedia(uint8_t lun, uint8_t lock);
523
+
524
+        bool LUNIsGood(uint8_t lun);
525
+        uint32_t GetCapacity(uint8_t lun);
526
+        uint16_t GetSectorSize(uint8_t lun);
527
+
528
+        // USBDeviceConfig implementation
529
+        uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
530
+        uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
531
+
532
+        uint8_t Release();
533
+        uint8_t Poll();
534
+
535
+        virtual uint8_t GetAddress() {
536
+                return bAddress;
537
+        };
538
+
539
+        // UsbConfigXtracter implementation
540
+        void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
541
+
542
+        virtual bool DEVCLASSOK(uint8_t klass) {
543
+                return (klass == USB_CLASS_MASS_STORAGE);
544
+        }
545
+
546
+        uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
547
+        uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
548
+
549
+private:
550
+        uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
551
+        uint8_t TestUnitReady(uint8_t lun);
552
+        uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
553
+        uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
554
+        uint8_t GetMaxLUN(uint8_t *max_lun);
555
+        uint8_t SetCurLUN(uint8_t lun);
556
+        void Reset();
557
+        uint8_t ResetRecovery();
558
+        uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
559
+        void ClearAllEP();
560
+        void CheckMedia();
561
+        bool CheckLUN(uint8_t lun);
562
+        uint8_t Page3F(uint8_t lun);
563
+        bool IsValidCBW(uint8_t size, uint8_t *pcbw);
564
+        bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
565
+
566
+        bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
567
+
568
+        uint8_t ClearEpHalt(uint8_t index);
569
+#if MS_WANT_PARSER
570
+        uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
571
+#endif
572
+        uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
573
+        uint8_t HandleUsbError(uint8_t error, uint8_t index);
574
+        uint8_t HandleSCSIError(uint8_t status);
575
+
576
+};
577
+
578
+#endif // __MASSTORAGE_H__

+ 235
- 0
Marlin/src/sd/usb_flashdrive/lib/max3421e.h 파일 보기

@@ -0,0 +1,235 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+#if !defined(_usb_h_) || defined(_max3421e_h_)
25
+#error "Never include max3421e.h directly; include Usb.h instead"
26
+#else
27
+
28
+#define _max3421e_h_
29
+
30
+/* MAX3421E register/bit names and bitmasks */
31
+
32
+/* Arduino pin definitions */
33
+/* pin numbers to port numbers */
34
+
35
+#define SE0     0
36
+#define SE1     1
37
+#define FSHOST  2
38
+#define LSHOST  3
39
+
40
+/* MAX3421E command byte format: rrrrr0wa where 'r' is register number  */
41
+//
42
+// MAX3421E Registers in HOST mode.
43
+//
44
+#define rRCVFIFO    0x08    //1<<3
45
+#define rSNDFIFO    0x10    //2<<3
46
+#define rSUDFIFO    0x20    //4<<3
47
+#define rRCVBC      0x30    //6<<3
48
+#define rSNDBC      0x38    //7<<3
49
+
50
+#define rUSBIRQ     0x68    //13<<3
51
+/* USBIRQ Bits  */
52
+#define bmVBUSIRQ   0x40    //b6
53
+#define bmNOVBUSIRQ 0x20    //b5
54
+#define bmOSCOKIRQ  0x01    //b0
55
+
56
+#define rUSBIEN     0x70    //14<<3
57
+/* USBIEN Bits  */
58
+#define bmVBUSIE    0x40    //b6
59
+#define bmNOVBUSIE  0x20    //b5
60
+#define bmOSCOKIE   0x01    //b0
61
+
62
+#define rUSBCTL     0x78    //15<<3
63
+/* USBCTL Bits  */
64
+#define bmCHIPRES   0x20    //b5
65
+#define bmPWRDOWN   0x10    //b4
66
+
67
+#define rCPUCTL     0x80    //16<<3
68
+/* CPUCTL Bits  */
69
+#define bmPUSLEWID1 0x80    //b7
70
+#define bmPULSEWID0 0x40    //b6
71
+#define bmIE        0x01    //b0
72
+
73
+#define rPINCTL     0x88    //17<<3
74
+/* PINCTL Bits  */
75
+#define bmFDUPSPI   0x10    //b4
76
+#define bmINTLEVEL  0x08    //b3
77
+#define bmPOSINT    0x04    //b2
78
+#define bmGPXB      0x02    //b1
79
+#define bmGPXA      0x01    //b0
80
+// GPX pin selections
81
+#define GPX_OPERATE 0x00
82
+#define GPX_VBDET   0x01
83
+#define GPX_BUSACT  0x02
84
+#define GPX_SOF     0x03
85
+
86
+#define rREVISION   0x90    //18<<3
87
+
88
+#define rIOPINS1    0xa0    //20<<3
89
+
90
+/* IOPINS1 Bits */
91
+#define bmGPOUT0    0x01
92
+#define bmGPOUT1    0x02
93
+#define bmGPOUT2    0x04
94
+#define bmGPOUT3    0x08
95
+#define bmGPIN0     0x10
96
+#define bmGPIN1     0x20
97
+#define bmGPIN2     0x40
98
+#define bmGPIN3     0x80
99
+
100
+#define rIOPINS2    0xa8    //21<<3
101
+/* IOPINS2 Bits */
102
+#define bmGPOUT4    0x01
103
+#define bmGPOUT5    0x02
104
+#define bmGPOUT6    0x04
105
+#define bmGPOUT7    0x08
106
+#define bmGPIN4     0x10
107
+#define bmGPIN5     0x20
108
+#define bmGPIN6     0x40
109
+#define bmGPIN7     0x80
110
+
111
+#define rGPINIRQ    0xb0    //22<<3
112
+/* GPINIRQ Bits */
113
+#define bmGPINIRQ0 0x01
114
+#define bmGPINIRQ1 0x02
115
+#define bmGPINIRQ2 0x04
116
+#define bmGPINIRQ3 0x08
117
+#define bmGPINIRQ4 0x10
118
+#define bmGPINIRQ5 0x20
119
+#define bmGPINIRQ6 0x40
120
+#define bmGPINIRQ7 0x80
121
+
122
+#define rGPINIEN    0xb8    //23<<3
123
+/* GPINIEN Bits */
124
+#define bmGPINIEN0 0x01
125
+#define bmGPINIEN1 0x02
126
+#define bmGPINIEN2 0x04
127
+#define bmGPINIEN3 0x08
128
+#define bmGPINIEN4 0x10
129
+#define bmGPINIEN5 0x20
130
+#define bmGPINIEN6 0x40
131
+#define bmGPINIEN7 0x80
132
+
133
+#define rGPINPOL    0xc0    //24<<3
134
+/* GPINPOL Bits */
135
+#define bmGPINPOL0 0x01
136
+#define bmGPINPOL1 0x02
137
+#define bmGPINPOL2 0x04
138
+#define bmGPINPOL3 0x08
139
+#define bmGPINPOL4 0x10
140
+#define bmGPINPOL5 0x20
141
+#define bmGPINPOL6 0x40
142
+#define bmGPINPOL7 0x80
143
+
144
+#define rHIRQ       0xc8    //25<<3
145
+/* HIRQ Bits */
146
+#define bmBUSEVENTIRQ   0x01   // indicates BUS Reset Done or BUS Resume
147
+#define bmRWUIRQ        0x02
148
+#define bmRCVDAVIRQ     0x04
149
+#define bmSNDBAVIRQ     0x08
150
+#define bmSUSDNIRQ      0x10
151
+#define bmCONDETIRQ     0x20
152
+#define bmFRAMEIRQ      0x40
153
+#define bmHXFRDNIRQ     0x80
154
+
155
+#define rHIEN           0xd0    //26<<3
156
+
157
+/* HIEN Bits */
158
+#define bmBUSEVENTIE    0x01
159
+#define bmRWUIE         0x02
160
+#define bmRCVDAVIE      0x04
161
+#define bmSNDBAVIE      0x08
162
+#define bmSUSDNIE       0x10
163
+#define bmCONDETIE      0x20
164
+#define bmFRAMEIE       0x40
165
+#define bmHXFRDNIE      0x80
166
+
167
+#define rMODE           0xd8    //27<<3
168
+
169
+/* MODE Bits */
170
+#define bmHOST          0x01
171
+#define bmLOWSPEED      0x02
172
+#define bmHUBPRE        0x04
173
+#define bmSOFKAENAB     0x08
174
+#define bmSEPIRQ        0x10
175
+#define bmDELAYISO      0x20
176
+#define bmDMPULLDN      0x40
177
+#define bmDPPULLDN      0x80
178
+
179
+#define rPERADDR    0xe0    //28<<3
180
+
181
+#define rHCTL       0xe8    //29<<3
182
+/* HCTL Bits */
183
+#define bmBUSRST        0x01
184
+#define bmFRMRST        0x02
185
+#define bmSAMPLEBUS     0x04
186
+#define bmSIGRSM        0x08
187
+#define bmRCVTOG0       0x10
188
+#define bmRCVTOG1       0x20
189
+#define bmSNDTOG0       0x40
190
+#define bmSNDTOG1       0x80
191
+
192
+#define rHXFR       0xf0    //30<<3
193
+/* Host transfer token values for writing the HXFR register (R30)   */
194
+/* OR this bit field with the endpoint number in bits 3:0               */
195
+#define tokSETUP  0x10  // HS=0, ISO=0, OUTNIN=0, SETUP=1
196
+#define tokIN     0x00  // HS=0, ISO=0, OUTNIN=0, SETUP=0
197
+#define tokOUT    0x20  // HS=0, ISO=0, OUTNIN=1, SETUP=0
198
+#define tokINHS   0x80  // HS=1, ISO=0, OUTNIN=0, SETUP=0
199
+#define tokOUTHS  0xA0  // HS=1, ISO=0, OUTNIN=1, SETUP=0
200
+#define tokISOIN  0x40  // HS=0, ISO=1, OUTNIN=0, SETUP=0
201
+#define tokISOOUT 0x60  // HS=0, ISO=1, OUTNIN=1, SETUP=0
202
+
203
+#define rHRSL       0xf8    //31<<3
204
+
205
+/* HRSL Bits */
206
+#define bmRCVTOGRD  0x10
207
+#define bmSNDTOGRD  0x20
208
+#define bmKSTATUS   0x40
209
+#define bmJSTATUS   0x80
210
+#define bmSE0       0x00    //SE0 - disconnect state
211
+#define bmSE1       0xc0    //SE1 - illegal state
212
+
213
+/* Host error result codes, the 4 LSB's in the HRSL register */
214
+#define hrSUCCESS   0x00
215
+#define hrBUSY      0x01
216
+#define hrBADREQ    0x02
217
+#define hrUNDEF     0x03
218
+#define hrNAK       0x04
219
+#define hrSTALL     0x05
220
+#define hrTOGERR    0x06
221
+#define hrWRONGPID  0x07
222
+#define hrBADBC     0x08
223
+#define hrPIDERR    0x09
224
+#define hrPKTERR    0x0A
225
+#define hrCRCERR    0x0B
226
+#define hrKERR      0x0C
227
+#define hrJERR      0x0D
228
+#define hrTIMEOUT   0x0E
229
+#define hrBABBLE    0x0F
230
+
231
+#define MODE_FS_HOST    (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB)
232
+#define MODE_LS_HOST    (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB)
233
+
234
+
235
+#endif //_max3421e_h_

+ 130
- 0
Marlin/src/sd/usb_flashdrive/lib/message.cpp 파일 보기

@@ -0,0 +1,130 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#include "../../../inc/MarlinConfigPre.h"
26
+
27
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
28
+
29
+#include "Usb.h"
30
+
31
+// 0x80 is the default (i.e. trace) to turn off set this global to something lower.
32
+// this allows for 126 other debugging levels.
33
+// TO-DO: Allow assignment to a different serial port by software
34
+int UsbDEBUGlvl = 0x80;
35
+
36
+void E_Notifyc(char c, int lvl) {
37
+        if(UsbDEBUGlvl < lvl) return;
38
+#if defined(ARDUINO) && ARDUINO >=100
39
+        USB_HOST_SERIAL.print(c);
40
+#else
41
+        USB_HOST_SERIAL.print(c, BYTE);
42
+#endif
43
+        //USB_HOST_SERIAL.flush();
44
+}
45
+
46
+void E_Notify(char const * msg, int lvl) {
47
+        if(UsbDEBUGlvl < lvl) return;
48
+        if(!msg) return;
49
+        char c;
50
+
51
+        while((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl);
52
+}
53
+
54
+void E_NotifyStr(char const * msg, int lvl) {
55
+        if(UsbDEBUGlvl < lvl) return;
56
+        if(!msg) return;
57
+        char c;
58
+
59
+        while((c = *msg++)) E_Notifyc(c, lvl);
60
+}
61
+
62
+void E_Notify(uint8_t b, int lvl) {
63
+        if(UsbDEBUGlvl < lvl) return;
64
+#if defined(ARDUINO) && ARDUINO >=100
65
+        USB_HOST_SERIAL.print(b);
66
+#else
67
+        USB_HOST_SERIAL.print(b, DEC);
68
+#endif
69
+        //USB_HOST_SERIAL.flush();
70
+}
71
+
72
+void E_Notify(double d, int lvl) {
73
+        if(UsbDEBUGlvl < lvl) return;
74
+        USB_HOST_SERIAL.print(d);
75
+        //USB_HOST_SERIAL.flush();
76
+}
77
+
78
+#ifdef DEBUG_USB_HOST
79
+
80
+void NotifyFailGetDevDescr(void) {
81
+        Notify(PSTR("\r\ngetDevDescr "), 0x80);
82
+}
83
+
84
+void NotifyFailSetDevTblEntry(void) {
85
+        Notify(PSTR("\r\nsetDevTblEn "), 0x80);
86
+}
87
+
88
+void NotifyFailGetConfDescr(void) {
89
+        Notify(PSTR("\r\ngetConf "), 0x80);
90
+}
91
+
92
+void NotifyFailSetConfDescr(void) {
93
+        Notify(PSTR("\r\nsetConf "), 0x80);
94
+}
95
+
96
+void NotifyFailGetDevDescr(uint8_t reason) {
97
+        NotifyFailGetDevDescr();
98
+        NotifyFail(reason);
99
+}
100
+
101
+void NotifyFailSetDevTblEntry(uint8_t reason) {
102
+        NotifyFailSetDevTblEntry();
103
+        NotifyFail(reason);
104
+
105
+}
106
+
107
+void NotifyFailGetConfDescr(uint8_t reason) {
108
+        NotifyFailGetConfDescr();
109
+        NotifyFail(reason);
110
+}
111
+
112
+void NotifyFailSetConfDescr(uint8_t reason) {
113
+        NotifyFailSetConfDescr();
114
+        NotifyFail(reason);
115
+}
116
+
117
+void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) {
118
+        Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
119
+        D_PrintHex<uint16_t > (VID, 0x80);
120
+        Notify(PSTR(" PID: "), 0x80);
121
+        D_PrintHex<uint16_t > (PID, 0x80);
122
+}
123
+
124
+void NotifyFail(uint8_t rcode) {
125
+        D_PrintHex<uint8_t > (rcode, 0x80);
126
+        Notify(PSTR("\r\n"), 0x80);
127
+}
128
+#endif // DEBUG_USB_HOST
129
+
130
+#endif // USB_FLASH_DRIVE_SUPPORT

+ 85
- 0
Marlin/src/sd/usb_flashdrive/lib/message.h 파일 보기

@@ -0,0 +1,85 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+#if !defined(_usb_h_) || defined(__MESSAGE_H__)
25
+#error "Never include message.h directly; include Usb.h instead"
26
+#else
27
+#define __MESSAGE_H__
28
+
29
+extern int UsbDEBUGlvl;
30
+
31
+void E_Notify(char const * msg, int lvl);
32
+void E_Notify(uint8_t b, int lvl);
33
+void E_NotifyStr(char const * msg, int lvl);
34
+void E_Notifyc(char c, int lvl);
35
+
36
+#ifdef DEBUG_USB_HOST
37
+#define Notify E_Notify
38
+#define NotifyStr E_NotifyStr
39
+#define Notifyc E_Notifyc
40
+void NotifyFailGetDevDescr(uint8_t reason);
41
+void NotifyFailSetDevTblEntry(uint8_t reason);
42
+void NotifyFailGetConfDescr(uint8_t reason);
43
+void NotifyFailSetConfDescr(uint8_t reason);
44
+void NotifyFailGetDevDescr(void);
45
+void NotifyFailSetDevTblEntry(void);
46
+void NotifyFailGetConfDescr(void);
47
+void NotifyFailSetConfDescr(void);
48
+void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID);
49
+void NotifyFail(uint8_t rcode);
50
+#else
51
+#define Notify(...) ((void)0)
52
+#define NotifyStr(...) ((void)0)
53
+#define Notifyc(...) ((void)0)
54
+#define NotifyFailGetDevDescr(...) ((void)0)
55
+#define NotifyFailSetDevTblEntry(...) ((void)0)
56
+#define NotifyFailGetConfDescr(...) ((void)0)
57
+#define NotifyFailGetDevDescr(...) ((void)0)
58
+#define NotifyFailSetDevTblEntry(...) ((void)0)
59
+#define NotifyFailGetConfDescr(...) ((void)0)
60
+#define NotifyFailSetConfDescr(...) ((void)0)
61
+#define NotifyFailUnknownDevice(...) ((void)0)
62
+#define NotifyFail(...) ((void)0)
63
+#endif
64
+
65
+template <class ERROR_TYPE>
66
+void ErrorMessage(uint8_t level, char const * msg, ERROR_TYPE rcode = 0) {
67
+#ifdef DEBUG_USB_HOST
68
+        Notify(msg, level);
69
+        Notify(PSTR(": "), level);
70
+        D_PrintHex<ERROR_TYPE > (rcode, level);
71
+        Notify(PSTR("\r\n"), level);
72
+#endif
73
+}
74
+
75
+template <class ERROR_TYPE>
76
+void ErrorMessage(char const * msg __attribute__((unused)), ERROR_TYPE rcode __attribute__((unused)) = 0) {
77
+#ifdef DEBUG_USB_HOST
78
+        Notify(msg, 0x80);
79
+        Notify(PSTR(": "), 0x80);
80
+        D_PrintHex<ERROR_TYPE > (rcode, 0x80);
81
+        Notify(PSTR("\r\n"), 0x80);
82
+#endif
83
+}
84
+
85
+#endif // __MESSAGE_H__

+ 81
- 0
Marlin/src/sd/usb_flashdrive/lib/parsetools.cpp 파일 보기

@@ -0,0 +1,81 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#include "../../../inc/MarlinConfigPre.h"
26
+
27
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
28
+
29
+#include "Usb.h"
30
+
31
+bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
32
+        if(!pBuf) {
33
+                Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
34
+                return false;
35
+        }
36
+        for(; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
37
+                pBuf[valueSize - countDown] = (**pp);
38
+
39
+        if(countDown)
40
+                return false;
41
+
42
+        countDown = valueSize;
43
+        return true;
44
+}
45
+
46
+bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me) {
47
+        switch(nStage) {
48
+                case 0:
49
+                        pBuf->valueSize = lenSize;
50
+                        theParser.Initialize(pBuf);
51
+                        nStage = 1;
52
+
53
+                case 1:
54
+                        if(!theParser.Parse(pp, pcntdn))
55
+                                return false;
56
+
57
+                        arLen = 0;
58
+                        arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue));
59
+                        arLenCntdn = arLen;
60
+                        nStage = 2;
61
+
62
+                case 2:
63
+                        pBuf->valueSize = valSize;
64
+                        theParser.Initialize(pBuf);
65
+                        nStage = 3;
66
+
67
+                case 3:
68
+                        for(; arLenCntdn; arLenCntdn--) {
69
+                                if(!theParser.Parse(pp, pcntdn))
70
+                                        return false;
71
+
72
+                                if(pf)
73
+                                        pf(pBuf, (arLen - arLenCntdn), me);
74
+                        }
75
+
76
+                        nStage = 0;
77
+        }
78
+        return true;
79
+}
80
+
81
+#endif // USB_FLASH_DRIVE_SUPPORT

+ 147
- 0
Marlin/src/sd/usb_flashdrive/lib/parsetools.h 파일 보기

@@ -0,0 +1,147 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#if !defined(_usb_h_) || defined(__PARSETOOLS_H__)
26
+#error "Never include parsetools.h directly; include Usb.h instead"
27
+#else
28
+#define __PARSETOOLS_H__
29
+
30
+struct MultiValueBuffer {
31
+        uint8_t valueSize;
32
+        void *pValue;
33
+} __attribute__((packed));
34
+
35
+class MultiByteValueParser {
36
+        uint8_t * pBuf;
37
+        uint8_t countDown;
38
+        uint8_t valueSize;
39
+
40
+public:
41
+
42
+        MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) {
43
+        };
44
+
45
+        const uint8_t* GetBuffer() {
46
+                return pBuf;
47
+        };
48
+
49
+        void Initialize(MultiValueBuffer * const pbuf) {
50
+                pBuf = (uint8_t*)pbuf->pValue;
51
+                countDown = valueSize = pbuf->valueSize;
52
+        };
53
+
54
+        bool Parse(uint8_t **pp, uint16_t *pcntdn);
55
+};
56
+
57
+class ByteSkipper {
58
+        uint8_t *pBuf;
59
+        uint8_t nStage;
60
+        uint16_t countDown;
61
+
62
+public:
63
+
64
+        ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {
65
+        };
66
+
67
+        void Initialize(MultiValueBuffer *pbuf) {
68
+                pBuf = (uint8_t*)pbuf->pValue;
69
+                countDown = 0;
70
+        };
71
+
72
+        bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) {
73
+                switch(nStage) {
74
+                        case 0:
75
+                                countDown = bytes_to_skip;
76
+                                nStage++;
77
+                        case 1:
78
+                                for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--);
79
+
80
+                                if(!countDown)
81
+                                        nStage = 0;
82
+                };
83
+                return (!countDown);
84
+        };
85
+};
86
+
87
+// Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser
88
+typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t count, const void *me);
89
+
90
+class PTPListParser {
91
+public:
92
+
93
+        enum ParseMode {
94
+                modeArray, modeRange/*, modeEnum*/
95
+        };
96
+
97
+private:
98
+        uint8_t nStage;
99
+        uint8_t enStage;
100
+
101
+        uint32_t arLen;
102
+        uint32_t arLenCntdn;
103
+
104
+        uint8_t lenSize; // size of the array length field in bytes
105
+        uint8_t valSize; // size of the array element in bytes
106
+
107
+        MultiValueBuffer *pBuf;
108
+
109
+        // The only parser for both size and array element parsing
110
+        MultiByteValueParser theParser;
111
+
112
+        uint8_t /*ParseMode*/ prsMode;
113
+
114
+public:
115
+
116
+        PTPListParser() :
117
+        nStage(0),
118
+        enStage(0),
119
+        arLen(0),
120
+        arLenCntdn(0),
121
+        lenSize(0),
122
+        valSize(0),
123
+        pBuf(NULL),
124
+        prsMode(modeArray) {
125
+        };
126
+
127
+        void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) {
128
+                pBuf = p;
129
+                lenSize = len_size;
130
+                valSize = val_size;
131
+                prsMode = mode;
132
+
133
+                if(prsMode == modeRange) {
134
+                        arLenCntdn = arLen = 3;
135
+                        nStage = 2;
136
+                } else {
137
+                        arLenCntdn = arLen = 0;
138
+                        nStage = 0;
139
+                }
140
+                enStage = 0;
141
+                theParser.Initialize(p);
142
+        };
143
+
144
+        bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL);
145
+};
146
+
147
+#endif // __PARSETOOLS_H__

+ 91
- 0
Marlin/src/sd/usb_flashdrive/lib/printhex.h 파일 보기

@@ -0,0 +1,91 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#if !defined(_usb_h_) || defined(__PRINTHEX_H__)
26
+#error "Never include printhex.h directly; include Usb.h instead"
27
+#else
28
+#define __PRINTHEX_H__
29
+
30
+void E_Notifyc(char c, int lvl);
31
+
32
+template <class T>
33
+void PrintHex(T val, int lvl) {
34
+        int num_nibbles = sizeof (T) * 2;
35
+
36
+        do {
37
+                char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
38
+                if(v > 57) v += 7;
39
+                E_Notifyc(v, lvl);
40
+        } while(--num_nibbles);
41
+}
42
+
43
+template <class T>
44
+void PrintBin(T val, int lvl) {
45
+        for(T mask = (((T)1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1)
46
+                if(val & mask)
47
+                        E_Notifyc('1', lvl);
48
+                else
49
+                        E_Notifyc('0', lvl);
50
+}
51
+
52
+template <class T>
53
+void SerialPrintHex(T val) {
54
+        int num_nibbles = sizeof (T) * 2;
55
+
56
+        do {
57
+                char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
58
+                if(v > 57) v += 7;
59
+                USB_HOST_SERIAL.print(v);
60
+        } while(--num_nibbles);
61
+}
62
+
63
+template <class T>
64
+void PrintHex2(Print *prn, T val) {
65
+        T mask = (((T)1) << (((sizeof (T) << 1) - 1) << 2));
66
+
67
+        while(mask > 1) {
68
+                if(val < mask)
69
+                        prn->print("0");
70
+
71
+                mask >>= 4;
72
+        }
73
+        prn->print((T)val, HEX);
74
+}
75
+
76
+template <class T> void D_PrintHex(T val __attribute__((unused)), int lvl __attribute__((unused))) {
77
+#ifdef DEBUG_USB_HOST
78
+        PrintHex<T > (val, lvl);
79
+#endif
80
+}
81
+
82
+template <class T>
83
+void D_PrintBin(T val, int lvl) {
84
+#ifdef DEBUG_USB_HOST
85
+        PrintBin<T > (val, lvl);
86
+#endif
87
+}
88
+
89
+
90
+
91
+#endif // __PRINTHEX_H__

+ 236
- 0
Marlin/src/sd/usb_flashdrive/lib/settings.h 파일 보기

@@ -0,0 +1,236 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#ifndef USB_HOST_SHIELD_SETTINGS_H
26
+#define USB_HOST_SHIELD_SETTINGS_H
27
+
28
+#include "../../../inc/MarlinConfig.h"
29
+
30
+#include "macros.h"
31
+
32
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
33
+  ////////////////////////////////////////////////////////////////////////////////
34
+  /* Added by Bill Greiman to speed up mass storage initialization with USB
35
+   * flash drives and simple USB hard drives.
36
+   * Disable this by defining DELAY(x) to be delay(x).
37
+   */
38
+  #define delay(x)  if((x) < 200) safe_delay(x)
39
+  /* Almost all USB flash drives and simple USB hard drives fail the write
40
+   * protect test and add 20 - 30 seconds to USB init.  Set SKIP_WRITE_PROTECT
41
+   * to nonzero to skip the test and assume the drive is writable.
42
+   */
43
+  #define SKIP_WRITE_PROTECT 1
44
+  /* Since Marlin only cares about USB flash drives, we only need one LUN. */
45
+  #define MASS_MAX_SUPPORTED_LUN 1
46
+#endif
47
+////////////////////////////////////////////////////////////////////////////////
48
+// SPI Configuration
49
+////////////////////////////////////////////////////////////////////////////////
50
+#ifndef USB_SPI
51
+  #define USB_SPI SPI
52
+  //#define USB_SPI SPI1
53
+#endif
54
+
55
+////////////////////////////////////////////////////////////////////////////////
56
+// DEBUGGING
57
+////////////////////////////////////////////////////////////////////////////////
58
+
59
+/* Set this to 1 to activate serial debugging */
60
+#define ENABLE_UHS_DEBUGGING 0
61
+
62
+/* This can be used to select which serial port to use for debugging if
63
+ * multiple serial ports are available.
64
+ * For example Serial3.
65
+ */
66
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
67
+  #define USB_HOST_SERIAL MYSERIAL0
68
+#endif
69
+
70
+#ifndef USB_HOST_SERIAL
71
+  #define USB_HOST_SERIAL Serial
72
+#endif
73
+
74
+////////////////////////////////////////////////////////////////////////////////
75
+// Manual board activation
76
+////////////////////////////////////////////////////////////////////////////////
77
+
78
+/* Set this to 1 if you are using an Arduino Mega ADK board with MAX3421e built-in */
79
+#define USE_UHS_MEGA_ADK 0 // If you are using Arduino 1.5.5 or newer there is no need to do this manually
80
+
81
+/* Set this to 1 if you are using a Black Widdow */
82
+#define USE_UHS_BLACK_WIDDOW 0
83
+
84
+/* Set this to a one to use the xmem2 lock. This is needed for multitasking and threading */
85
+#define USE_XMEM_SPI_LOCK 0
86
+
87
+////////////////////////////////////////////////////////////////////////////////
88
+// Wii IR camera
89
+////////////////////////////////////////////////////////////////////////////////
90
+
91
+/* Set this to 1 to activate code for the Wii IR camera */
92
+#define ENABLE_WII_IR_CAMERA 0
93
+
94
+////////////////////////////////////////////////////////////////////////////////
95
+// MASS STORAGE
96
+////////////////////////////////////////////////////////////////////////////////
97
+// ******* IMPORTANT *******
98
+// Set this to 1 to support single LUN devices, and save RAM. -- I.E. thumb drives.
99
+// Each LUN needs ~13 bytes to be able to track the state of each unit.
100
+#ifndef MASS_MAX_SUPPORTED_LUN
101
+  #define MASS_MAX_SUPPORTED_LUN 8
102
+#endif
103
+
104
+////////////////////////////////////////////////////////////////////////////////
105
+// Set to 1 to use the faster spi4teensy3 driver.
106
+////////////////////////////////////////////////////////////////////////////////
107
+#ifndef USE_SPI4TEENSY3
108
+  #define USE_SPI4TEENSY3 1
109
+#endif
110
+
111
+// Disabled on the Teensy LC, as it is incompatible for now
112
+#ifdef __MKL26Z64__
113
+  #undef USE_SPI4TEENSY3
114
+  #define USE_SPI4TEENSY3 0
115
+#endif
116
+
117
+////////////////////////////////////////////////////////////////////////////////
118
+// AUTOMATIC Settings
119
+////////////////////////////////////////////////////////////////////////////////
120
+
121
+// No user serviceable parts below this line.
122
+// DO NOT change anything below here unless you are a developer!
123
+
124
+//#include "version_helper.h"
125
+
126
+#if defined(__GNUC__) && defined(__AVR__)
127
+  #ifndef GCC_VERSION
128
+    #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
129
+  #endif
130
+  #if GCC_VERSION < 40602 // Test for GCC < 4.6.2
131
+    #ifdef PROGMEM
132
+      #undef PROGMEM
133
+      #define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4
134
+      #ifdef PSTR
135
+        #undef PSTR
136
+        #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) // Copied from pgmspace.h in avr-libc source
137
+      #endif
138
+    #endif
139
+  #endif
140
+#endif
141
+
142
+#if !defined(DEBUG_USB_HOST) && ENABLE_UHS_DEBUGGING
143
+  #define DEBUG_USB_HOST
144
+#endif
145
+
146
+#if !defined(WIICAMERA) && ENABLE_WII_IR_CAMERA
147
+  #define WIICAMERA
148
+#endif
149
+
150
+// To use some other locking (e.g. freertos),
151
+// define XMEM_ACQUIRE_SPI and XMEM_RELEASE_SPI to point to your lock and unlock.
152
+// NOTE: NO argument is passed. You have to do this within your routine for
153
+// whatever you are using to lock and unlock.
154
+#if !defined(XMEM_ACQUIRE_SPI)
155
+  #if USE_XMEM_SPI_LOCK || defined(USE_MULTIPLE_APP_API)
156
+    #include <xmem.h>
157
+  #else
158
+    #define XMEM_ACQUIRE_SPI() (void(0))
159
+    #define XMEM_RELEASE_SPI() (void(0))
160
+  #endif
161
+#endif
162
+
163
+#if !defined(EXT_RAM) && defined(EXT_RAM_STACK) || defined(EXT_RAM_HEAP)
164
+  #include <xmem.h>
165
+#else
166
+  #define EXT_RAM 0
167
+#endif
168
+
169
+#if defined(CORE_TEENSY) && defined(KINETISK)
170
+  #define USING_SPI4TEENSY3 USE_SPI4TEENSY3
171
+#else
172
+  #define USING_SPI4TEENSY3 0
173
+#endif
174
+#if ((defined(ARDUINO_SAM_DUE) && defined(__SAM3X8E__)) || defined(__ARDUINO_X86__) || ARDUINO >= 10600) && !USING_SPI4TEENSY3
175
+  #include <SPI.h> // Use the Arduino SPI library for the Arduino Due, Intel Galileo 1 & 2, Intel Edison or if the SPI library with transaction is available
176
+#endif
177
+#ifdef RBL_NRF51822
178
+  #include <nrf_gpio.h>
179
+  #include <SPI_Master.h>
180
+  #define SPI SPI_Master
181
+  #define MFK_CASTUINT8T (uint8_t) // RBLs return type for sizeof needs casting to uint8_t
182
+#endif
183
+#if defined(__PIC32MX__) || defined(__PIC32MZ__)
184
+  #include <../../../../hardware/pic32/libraries/SPI/SPI.h> // Hack to use the SPI library
185
+#endif
186
+
187
+#if defined(ESP8266) || defined(ESP32)
188
+  #define MFK_CASTUINT8T (uint8_t) // ESP return type for sizeof needs casting to uint8_t
189
+#endif
190
+
191
+#ifdef STM32F4
192
+  #include "stm32f4xx_hal.h"
193
+  extern SPI_HandleTypeDef SPI_Handle; // Needed to be declared in your main.cpp
194
+#endif
195
+
196
+// Fix defines on Arduino Due
197
+#ifdef ARDUINO_SAM_DUE
198
+  #ifdef tokSETUP
199
+    #undef tokSETUP
200
+  #endif
201
+  #ifdef tokIN
202
+    #undef tokIN
203
+  #endif
204
+  #ifdef tokOUT
205
+    #undef tokOUT
206
+  #endif
207
+  #ifdef tokINHS
208
+    #undef tokINHS
209
+  #endif
210
+  #ifdef tokOUTHS
211
+    #undef tokOUTHS
212
+  #endif
213
+#endif
214
+
215
+// Set defaults
216
+#ifndef MFK_CASTUINT8T
217
+  #define MFK_CASTUINT8T
218
+#endif
219
+
220
+// Workaround issue: https://github.com/esp8266/Arduino/issues/2078
221
+#ifdef ESP8266
222
+  #undef PROGMEM
223
+  #define PROGMEM
224
+#undef PSTR
225
+  #define PSTR(s) (s)
226
+#undef pgm_read_byte
227
+  #define pgm_read_byte(addr) (*reinterpret_cast<const uint8_t*>(addr))
228
+  #undef pgm_read_word
229
+  #define pgm_read_word(addr) (*reinterpret_cast<const uint16_t*>(addr))
230
+#endif
231
+
232
+#ifdef ARDUINO_ESP8266_WIFIO
233
+  #error "This board is currently not supported"
234
+#endif
235
+
236
+#endif /* SETTINGS_H */

+ 173
- 0
Marlin/src/sd/usb_flashdrive/lib/usb_ch9.h 파일 보기

@@ -0,0 +1,173 @@
1
+/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2
+
3
+This program is free software; you can redistribute it and/or modify
4
+it under the terms of the GNU General Public License as published by
5
+the Free Software Foundation; either version 2 of the License, or
6
+(at your option) any later version.
7
+
8
+This program is distributed in the hope that it will be useful,
9
+but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+GNU General Public License for more details.
12
+
13
+You should have received a copy of the GNU General Public License
14
+along with this program; if not, write to the Free Software
15
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
+
17
+Contact information
18
+-------------------
19
+
20
+Circuits At Home, LTD
21
+Web      :  http://www.circuitsathome.com
22
+e-mail   :  support@circuitsathome.com
23
+ */
24
+
25
+#if !defined(_usb_h_) || defined(_ch9_h_)
26
+#error "Never include usb_ch9.h directly; include Usb.h instead"
27
+#else
28
+
29
+/* USB chapter 9 structures */
30
+#define _ch9_h_
31
+
32
+/* Misc.USB constants */
33
+#define DEV_DESCR_LEN   18      //device descriptor length
34
+#define CONF_DESCR_LEN  9       //configuration descriptor length
35
+#define INTR_DESCR_LEN  9       //interface descriptor length
36
+#define EP_DESCR_LEN    7       //endpoint descriptor length
37
+
38
+/* Standard Device Requests */
39
+
40
+#define USB_REQUEST_GET_STATUS                  0       // Standard Device Request - GET STATUS
41
+#define USB_REQUEST_CLEAR_FEATURE               1       // Standard Device Request - CLEAR FEATURE
42
+#define USB_REQUEST_SET_FEATURE                 3       // Standard Device Request - SET FEATURE
43
+#define USB_REQUEST_SET_ADDRESS                 5       // Standard Device Request - SET ADDRESS
44
+#define USB_REQUEST_GET_DESCRIPTOR              6       // Standard Device Request - GET DESCRIPTOR
45
+#define USB_REQUEST_SET_DESCRIPTOR              7       // Standard Device Request - SET DESCRIPTOR
46
+#define USB_REQUEST_GET_CONFIGURATION           8       // Standard Device Request - GET CONFIGURATION
47
+#define USB_REQUEST_SET_CONFIGURATION           9       // Standard Device Request - SET CONFIGURATION
48
+#define USB_REQUEST_GET_INTERFACE               10      // Standard Device Request - GET INTERFACE
49
+#define USB_REQUEST_SET_INTERFACE               11      // Standard Device Request - SET INTERFACE
50
+#define USB_REQUEST_SYNCH_FRAME                 12      // Standard Device Request - SYNCH FRAME
51
+
52
+#define USB_FEATURE_ENDPOINT_HALT               0       // CLEAR/SET FEATURE - Endpoint Halt
53
+#define USB_FEATURE_DEVICE_REMOTE_WAKEUP        1       // CLEAR/SET FEATURE - Device remote wake-up
54
+#define USB_FEATURE_TEST_MODE                   2       // CLEAR/SET FEATURE - Test mode
55
+
56
+/* Setup Data Constants */
57
+
58
+#define USB_SETUP_HOST_TO_DEVICE                0x00    // Device Request bmRequestType transfer direction - host to device transfer
59
+#define USB_SETUP_DEVICE_TO_HOST                0x80    // Device Request bmRequestType transfer direction - device to host transfer
60
+#define USB_SETUP_TYPE_STANDARD                 0x00    // Device Request bmRequestType type - standard
61
+#define USB_SETUP_TYPE_CLASS                    0x20    // Device Request bmRequestType type - class
62
+#define USB_SETUP_TYPE_VENDOR                   0x40    // Device Request bmRequestType type - vendor
63
+#define USB_SETUP_RECIPIENT_DEVICE              0x00    // Device Request bmRequestType recipient - device
64
+#define USB_SETUP_RECIPIENT_INTERFACE           0x01    // Device Request bmRequestType recipient - interface
65
+#define USB_SETUP_RECIPIENT_ENDPOINT            0x02    // Device Request bmRequestType recipient - endpoint
66
+#define USB_SETUP_RECIPIENT_OTHER               0x03    // Device Request bmRequestType recipient - other
67
+
68
+/* USB descriptors  */
69
+
70
+#define USB_DESCRIPTOR_DEVICE                   0x01    // bDescriptorType for a Device Descriptor.
71
+#define USB_DESCRIPTOR_CONFIGURATION            0x02    // bDescriptorType for a Configuration Descriptor.
72
+#define USB_DESCRIPTOR_STRING                   0x03    // bDescriptorType for a String Descriptor.
73
+#define USB_DESCRIPTOR_INTERFACE                0x04    // bDescriptorType for an Interface Descriptor.
74
+#define USB_DESCRIPTOR_ENDPOINT                 0x05    // bDescriptorType for an Endpoint Descriptor.
75
+#define USB_DESCRIPTOR_DEVICE_QUALIFIER         0x06    // bDescriptorType for a Device Qualifier.
76
+#define USB_DESCRIPTOR_OTHER_SPEED              0x07    // bDescriptorType for a Other Speed Configuration.
77
+#define USB_DESCRIPTOR_INTERFACE_POWER          0x08    // bDescriptorType for Interface Power.
78
+#define USB_DESCRIPTOR_OTG                      0x09    // bDescriptorType for an OTG Descriptor.
79
+
80
+#define HID_DESCRIPTOR_HID                      0x21
81
+
82
+
83
+
84
+/* OTG SET FEATURE Constants    */
85
+#define OTG_FEATURE_B_HNP_ENABLE                3       // SET FEATURE OTG - Enable B device to perform HNP
86
+#define OTG_FEATURE_A_HNP_SUPPORT               4       // SET FEATURE OTG - A device supports HNP
87
+#define OTG_FEATURE_A_ALT_HNP_SUPPORT           5       // SET FEATURE OTG - Another port on the A device supports HNP
88
+
89
+/* USB Endpoint Transfer Types  */
90
+#define USB_TRANSFER_TYPE_CONTROL               0x00    // Endpoint is a control endpoint.
91
+#define USB_TRANSFER_TYPE_ISOCHRONOUS           0x01    // Endpoint is an isochronous endpoint.
92
+#define USB_TRANSFER_TYPE_BULK                  0x02    // Endpoint is a bulk endpoint.
93
+#define USB_TRANSFER_TYPE_INTERRUPT             0x03    // Endpoint is an interrupt endpoint.
94
+#define bmUSB_TRANSFER_TYPE                     0x03    // bit mask to separate transfer type from ISO attributes
95
+
96
+
97
+/* Standard Feature Selectors for CLEAR_FEATURE Requests    */
98
+#define USB_FEATURE_ENDPOINT_STALL              0       // Endpoint recipient
99
+#define USB_FEATURE_DEVICE_REMOTE_WAKEUP        1       // Device recipient
100
+#define USB_FEATURE_TEST_MODE                   2       // Device recipient
101
+
102
+/* descriptor data structures */
103
+
104
+/* Device descriptor structure */
105
+typedef struct {
106
+        uint8_t bLength; // Length of this descriptor.
107
+        uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
108
+        uint16_t bcdUSB; // USB Spec Release Number (BCD).
109
+        uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
110
+        uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
111
+        uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
112
+        uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
113
+        uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
114
+        uint16_t idProduct; // Product ID (assigned by the manufacturer).
115
+        uint16_t bcdDevice; // Device release number (BCD).
116
+        uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
117
+        uint8_t iProduct; // Index of String Descriptor describing the product.
118
+        uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
119
+        uint8_t bNumConfigurations; // Number of possible configurations.
120
+} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
121
+
122
+/* Configuration descriptor structure */
123
+typedef struct {
124
+        uint8_t bLength; // Length of this descriptor.
125
+        uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
126
+        uint16_t wTotalLength; // Total length of all descriptors for this configuration.
127
+        uint8_t bNumInterfaces; // Number of interfaces in this configuration.
128
+        uint8_t bConfigurationValue; // Value of this configuration (1 based).
129
+        uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
130
+        uint8_t bmAttributes; // Configuration characteristics.
131
+        uint8_t bMaxPower; // Maximum power consumed by this configuration.
132
+} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
133
+
134
+/* Interface descriptor structure */
135
+typedef struct {
136
+        uint8_t bLength; // Length of this descriptor.
137
+        uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
138
+        uint8_t bInterfaceNumber; // Number of this interface (0 based).
139
+        uint8_t bAlternateSetting; // Value of this alternate interface setting.
140
+        uint8_t bNumEndpoints; // Number of endpoints in this interface.
141
+        uint8_t bInterfaceClass; // Class code (assigned by the USB-IF).  0xFF-Vendor specific.
142
+        uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
143
+        uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF).  0xFF-Vendor specific.
144
+        uint8_t iInterface; // Index of String Descriptor describing the interface.
145
+} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
146
+
147
+/* Endpoint descriptor structure */
148
+typedef struct {
149
+        uint8_t bLength; // Length of this descriptor.
150
+        uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
151
+        uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
152
+        uint8_t bmAttributes; // Endpoint transfer type.
153
+        uint16_t wMaxPacketSize; // Maximum packet size.
154
+        uint8_t bInterval; // Polling interval in frames.
155
+} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
156
+
157
+/* HID descriptor */
158
+typedef struct {
159
+        uint8_t bLength;
160
+        uint8_t bDescriptorType;
161
+        uint16_t bcdHID; // HID class specification release
162
+        uint8_t bCountryCode;
163
+        uint8_t bNumDescriptors; // Number of additional class specific descriptors
164
+        uint8_t bDescrType; // Type of class descriptor
165
+        uint16_t wDescriptorLength; // Total size of the Report descriptor
166
+} __attribute__((packed)) USB_HID_DESCRIPTOR;
167
+
168
+typedef struct {
169
+        uint8_t bDescrType; // Type of class descriptor
170
+        uint16_t wDescriptorLength; // Total size of the Report descriptor
171
+} __attribute__((packed)) HID_CLASS_DESCRIPTOR_LEN_AND_TYPE;
172
+
173
+#endif // _ch9_h_

+ 187
- 0
Marlin/src/sd/usb_flashdrive/usb-2.0-host-library-changes.patch 파일 보기

@@ -0,0 +1,187 @@
1
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/masstorage.cpp lib/masstorage.cpp
2
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/masstorage.cpp	2018-09-21 10:19:36.107502252 -0600
3
++++ lib/masstorage.cpp	2018-09-21 09:46:19.620175519 -0600
4
+@@ -24,6 +24,8 @@
5
+ 
6
+ #include "masstorage.h"
7
+ 
8
++#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
9
++
10
+ const uint8_t BulkOnly::epDataInIndex = 1;
11
+ const uint8_t BulkOnly::epDataOutIndex = 2;
12
+ const uint8_t BulkOnly::epInterruptInIndex = 3;
13
+@@ -796,6 +798,9 @@
14
+                 buf[i] = 0x00;
15
+         }
16
+         WriteOk[lun] = true;
17
++        #if ENABLED(USB_FLASH_DRIVE_SUPPORT) && defined(SKIP_WRITE_PROTECT)
18
++          return 0;
19
++        #endif
20
+         uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
21
+         if(!rc) {
22
+                 WriteOk[lun] = ((buf[2] & 0x80) == 0);
23
+@@ -1271,3 +1276,5 @@
24
+         return MASS_ERR_NOT_IMPLEMENTED;
25
+ #endif
26
+ }
27
++
28
++#endif // USB_FLASH_DRIVE_SUPPORT
29
+\ No newline at end of file
30
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/message.cpp lib/message.cpp
31
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/message.cpp	2018-09-21 10:20:15.995647957 -0600
32
++++ lib/message.cpp	2018-09-19 07:43:46.520339375 -0600
33
+@@ -23,6 +23,9 @@
34
+  */
35
+ 
36
+ #include "Usb.h"
37
++
38
++#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
39
++
40
+ // 0x80 is the default (i.e. trace) to turn off set this global to something lower.
41
+ // this allows for 126 other debugging levels.
42
+ // TO-DO: Allow assignment to a different serial port by software
43
+@@ -120,4 +123,6 @@
44
+         D_PrintHex<uint8_t > (rcode, 0x80);
45
+         Notify(PSTR("\r\n"), 0x80);
46
+ }
47
+-#endif
48
++#endif // DEBUG_USB_HOST
49
++
50
++#endif // USB_FLASH_DRIVE_SUPPORT
51
+\ No newline at end of file
52
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/parsetools.cpp lib/parsetools.cpp
53
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/parsetools.cpp	2018-09-21 10:21:16.215867769 -0600
54
++++ lib/parsetools.cpp	2018-09-19 07:43:46.520339375 -0600
55
+@@ -23,6 +23,8 @@
56
+  */
57
+ #include "Usb.h"
58
+ 
59
++#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
60
++
61
+ bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
62
+         if(!pBuf) {
63
+                 Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
64
+@@ -72,3 +74,5 @@
65
+         }
66
+         return true;
67
+ }
68
++
69
++#endif // USB_FLASH_DRIVE_SUPPORT
70
+\ No newline at end of file
71
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/settings.h lib/settings.h
72
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/settings.h	2018-09-21 10:22:21.792106872 -0600
73
++++ lib/settings.h	2018-09-21 10:01:53.383594081 -0600
74
+@@ -25,7 +25,21 @@
75
+ #ifndef USB_HOST_SHIELD_SETTINGS_H
76
+ #define USB_HOST_SHIELD_SETTINGS_H
77
+ #include "macros.h"
78
+-
79
++#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
80
++  ////////////////////////////////////////////////////////////////////////////////
81
++  /* Added by Bill Greiman to speed up mass storage initialization with USB
82
++   * flash drives and simple USB hard drives.
83
++   * Disable this by defining DELAY(x) to be delay(x).
84
++   */
85
++  #define delay(x)  if((x) < 200) safe_delay(x)
86
++  /* Almost all USB flash drives and simple USB hard drives fail the write
87
++   * protect test and add 20 - 30 seconds to USB init.  Set SKIP_WRITE_PROTECT
88
++   * to nonzero to skip the test and assume the drive is writable.
89
++   */
90
++  #define SKIP_WRITE_PROTECT 1
91
++  /* Since Marlin only cares about USB flash drives, we only need one LUN. */
92
++  #define MASS_MAX_SUPPORTED_LUN 1
93
++#endif
94
+ ////////////////////////////////////////////////////////////////////////////////
95
+ // SPI Configuration
96
+ ////////////////////////////////////////////////////////////////////////////////
97
+@@ -45,6 +59,10 @@
98
+  * multiple serial ports are available.
99
+  * For example Serial3.
100
+  */
101
++#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
102
++  #define USB_HOST_SERIAL MYSERIAL0
103
++#endif
104
++
105
+ #ifndef USB_HOST_SERIAL
106
+ #define USB_HOST_SERIAL Serial
107
+ #endif
108
+@@ -99,7 +117,7 @@
109
+ // No user serviceable parts below this line.
110
+ // DO NOT change anything below here unless you are a developer!
111
+ 
112
+-#include "version_helper.h"
113
++//#include "version_helper.h"
114
+ 
115
+ #if defined(__GNUC__) && defined(__AVR__)
116
+ #ifndef GCC_VERSION
117
+@@ -149,7 +167,6 @@
118
+ #else
119
+ #define USING_SPI4TEENSY3 0
120
+ #endif
121
+-
122
+ #if ((defined(ARDUINO_SAM_DUE) && defined(__SAM3X8E__)) || defined(__ARDUINO_X86__) || ARDUINO >= 10600) && !USING_SPI4TEENSY3
123
+ #include <SPI.h> // Use the Arduino SPI library for the Arduino Due, Intel Galileo 1 & 2, Intel Edison or if the SPI library with transaction is available
124
+ #endif
125
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/UsbCore.h lib/UsbCore.h
126
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/UsbCore.h	2018-09-21 10:23:09.348280107 -0600
127
++++ lib/UsbCore.h	2018-09-19 07:43:46.520339375 -0600
128
+@@ -32,7 +32,10 @@
129
+ //#define USB_METHODS_INLINE
130
+ 
131
+ /* shield pins. First parameter - SS pin, second parameter - INT pin */
132
+-#ifdef BOARD_BLACK_WIDDOW
133
++
134
++#if defined(__MARLIN_H__)
135
++typedef MAX3421e MAX3421E; // Marlin redefines this class in "../usb_host.h"
136
++#elif defined(BOARD_BLACK_WIDDOW)
137
+ typedef MAX3421e<P6, P3> MAX3421E; // Black Widow
138
+ #elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
139
+ #if EXT_RAM
140
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.cpp lib/Usb.cpp
141
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.cpp	2018-09-21 10:23:20.732321559 -0600
142
++++ lib/Usb.cpp	2018-09-19 07:43:46.520339375 -0600
143
+@@ -25,6 +25,8 @@
144
+ 
145
+ #include "Usb.h"
146
+ 
147
++#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
148
++
149
+ static uint8_t usb_error = 0;
150
+ static uint8_t usb_task_state;
151
+ 
152
+@@ -825,3 +827,4 @@
153
+ }
154
+ 
155
+ #endif // defined(USB_METHODS_INLINE)
156
++#endif // USB_FLASH_DRIVE_SUPPORT
157
+diff -Naur /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.h lib/Usb.h
158
+--- /home/aleph/Downloads/USB_Host_Shield_2.0-master/Usb.h	2018-09-21 10:23:33.756368972 -0600
159
++++ lib/Usb.h	2018-09-19 07:43:46.520339375 -0600
160
+@@ -25,6 +25,8 @@
161
+ #ifndef _usb_h_
162
+ #define _usb_h_
163
+ 
164
++#include "../../../Marlin.h"
165
++
166
+ // WARNING: Do not change the order of includes, or stuff will break!
167
+ #include <inttypes.h>
168
+ #include <stddef.h>
169
+@@ -34,13 +36,15 @@
170
+ #include "settings.h"
171
+ #include "printhex.h"
172
+ #include "message.h"
173
++
174
+ #include "hexdump.h"
175
+-#include "sink_parser.h"
176
++//#include "sink_parser.h"
177
+ #include "max3421e.h"
178
+ #include "address.h"
179
+-#include "avrpins.h"
180
++//#include "avrpins.h"
181
+ #include "usb_ch9.h"
182
+-#include "usbhost.h"
183
++//#include "usbhost.h"
184
++#include "../usb_host.h"
185
+ #include "UsbCore.h"
186
+ #include "parsetools.h"
187
+ #include "confdescparser.h"

+ 213
- 0
Marlin/src/sd/usb_flashdrive/usb_host.cpp 파일 보기

@@ -0,0 +1,213 @@
1
+/****************
2
+ * usb_host.cpp *
3
+ ****************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+/* What follows is a modified version of the MAX3421e originally defined in
23
+ * lib/usbhost.c". This has been rewritten to use SPI routines from the
24
+ * Marlin HAL */
25
+
26
+#include "../../inc/MarlinConfigPre.h"
27
+
28
+#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
29
+
30
+#include "lib/Usb.h"
31
+#include "usb_host.h"
32
+
33
+uint8_t MAX3421e::vbusState = 0;
34
+
35
+// constructor
36
+void MAX3421e::cs() {
37
+  WRITE(USB_CS_PIN,0);
38
+}
39
+
40
+void MAX3421e::ncs() {
41
+  WRITE(USB_CS_PIN,1);
42
+}
43
+
44
+// write single byte into MAX3421 register
45
+void MAX3421e::regWr(uint8_t reg, uint8_t data) {
46
+  cs();
47
+  spiSend(reg | 0x02);
48
+  spiSend(data);
49
+  ncs();
50
+};
51
+
52
+// multiple-byte write
53
+// return a pointer to memory position after last written
54
+uint8_t* MAX3421e::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
55
+  cs();
56
+  spiSend(reg | 0x02);
57
+  while (nbytes--) spiSend(*data_p++);
58
+  ncs();
59
+  return data_p;
60
+}
61
+
62
+// GPIO write
63
+// GPIO byte is split between 2 registers, so two writes are needed to write one byte
64
+
65
+// GPOUT bits are in the low nybble. 0-3 in IOPINS1, 4-7 in IOPINS2
66
+void MAX3421e::gpioWr(uint8_t data) {
67
+  regWr(rIOPINS1, data);
68
+  regWr(rIOPINS2, data >> 4);
69
+}
70
+
71
+// single host register read
72
+uint8_t MAX3421e::regRd(uint8_t reg) {
73
+  cs();
74
+  spiSend(reg);
75
+  uint8_t rv = spiRec();
76
+  ncs();
77
+  return rv;
78
+}
79
+// multiple-byte register read
80
+
81
+// return a pointer to a memory position after last read
82
+uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
83
+  cs();
84
+  spiSend(reg);
85
+  while (nbytes--) *data_p++ = spiRec();
86
+  ncs();
87
+  return data_p;
88
+}
89
+// GPIO read. See gpioWr for explanation
90
+
91
+// GPIN pins are in high nybbles of IOPINS1, IOPINS2
92
+uint8_t MAX3421e::gpioRd() {
93
+  return (regRd(rIOPINS2) & 0xf0) | // pins 4-7, clean lower nybble
94
+         (regRd(rIOPINS1)   >> 4);  // shift low bits and OR with upper from previous operation.
95
+}
96
+
97
+// reset MAX3421e. Returns false if PLL failed to stabilize 1 second after reset
98
+bool MAX3421e::reset() {
99
+  regWr(rUSBCTL, bmCHIPRES);
100
+  regWr(rUSBCTL, 0x00);
101
+  for (uint8_t i = 100; i--;) {
102
+    if (regRd(rUSBIRQ) & bmOSCOKIRQ) return true;
103
+    delay(10);
104
+  }
105
+  return false;
106
+}
107
+
108
+// initialize MAX3421e. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not
109
+bool MAX3421e::start() {
110
+  // Initialize pins and SPI bus
111
+
112
+  SET_OUTPUT(SDSS);
113
+  SET_INPUT(USB_INTR_PIN);
114
+  ncs();
115
+  spiBegin();
116
+
117
+  spiInit(
118
+    #ifdef SPI_SPEED
119
+      SPI_SPEED
120
+    #else
121
+      SPI_FULL_SPEED
122
+    #endif
123
+  );
124
+
125
+  // MAX3421e - full-duplex, level interrupt, vbus off.
126
+  regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
127
+
128
+  const uint8_t revision = regRd(rREVISION);
129
+  if (revision == 0x00 || revision == 0xFF) {
130
+    SERIAL_ECHOLNPAIR("Revision register appears incorrect on MAX3421e initialization, got ", revision);
131
+    return false;
132
+  }
133
+
134
+  if (!reset()) {
135
+    SERIAL_ECHOLNPGM("OSCOKIRQ hasn't asserted in time");
136
+    return false;
137
+  }
138
+
139
+  // Delay a minimum of 1 second to ensure any capacitors are drained.
140
+  // 1 second is required to make sure we do not smoke a Microdrive!
141
+
142
+  delay(1000);
143
+
144
+  regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
145
+  regWr(rHIEN, bmCONDETIE | bmFRAMEIE); // connection detection
146
+
147
+  // check if device is connected
148
+  regWr(rHCTL, bmSAMPLEBUS); // sample USB bus
149
+  while (!(regRd(rHCTL) & bmSAMPLEBUS)) delay(10); // wait for sample operation to finish
150
+
151
+  busprobe(); // check if anything is connected
152
+
153
+  regWr(rHIRQ, bmCONDETIRQ); // clear connection detect interrupt
154
+  regWr(rCPUCTL, 0x01);      // enable interrupt pin
155
+
156
+  // GPX pin on. This is done here so that busprobe will fail if we have a switch connected.
157
+  regWr(rPINCTL, bmFDUPSPI | bmINTLEVEL);
158
+
159
+  return true;
160
+}
161
+
162
+// Probe bus to determine device presence and speed. Switch host to this speed.
163
+void MAX3421e::busprobe() {
164
+  // Switch on just the J & K bits
165
+  switch (regRd(rHRSL) & (bmJSTATUS | bmKSTATUS)) {
166
+    case bmJSTATUS:
167
+      if ((regRd(rMODE) & bmLOWSPEED) == 0) {
168
+        regWr(rMODE, MODE_FS_HOST); // start full-speed host
169
+        vbusState = FSHOST;
170
+      }
171
+      else {
172
+        regWr(rMODE, MODE_LS_HOST); // start low-speed host
173
+        vbusState = LSHOST;
174
+      }
175
+      break;
176
+    case bmKSTATUS:
177
+      if ((regRd(rMODE) & bmLOWSPEED) == 0) {
178
+        regWr(rMODE, MODE_LS_HOST); // start low-speed host
179
+        vbusState = LSHOST;
180
+      }
181
+      else {
182
+        regWr(rMODE, MODE_FS_HOST); // start full-speed host
183
+        vbusState = FSHOST;
184
+      }
185
+      break;
186
+    case bmSE1: // illegal state
187
+      vbusState = SE1;
188
+      break;
189
+    case bmSE0: // disconnected state
190
+      regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST | bmSEPIRQ);
191
+      vbusState = SE0;
192
+      break;
193
+  }
194
+}
195
+
196
+// MAX3421 state change task and interrupt handler
197
+uint8_t MAX3421e::Task(void) {
198
+  return READ(USB_INTR_PIN) ? 0 : IntHandler();
199
+}
200
+
201
+uint8_t MAX3421e::IntHandler() {
202
+  uint8_t HIRQ = regRd(rHIRQ), // determine interrupt source
203
+          HIRQ_sendback = 0x00;
204
+  if (HIRQ & bmCONDETIRQ) {
205
+    busprobe();
206
+    HIRQ_sendback |= bmCONDETIRQ;
207
+  }
208
+  // End HIRQ interrupts handling, clear serviced IRQs
209
+  regWr(rHIRQ, HIRQ_sendback);
210
+  return HIRQ_sendback;
211
+}
212
+
213
+#endif // USB_FLASH_DRIVE_SUPPORT

+ 61
- 0
Marlin/src/sd/usb_flashdrive/usb_host.h 파일 보기

@@ -0,0 +1,61 @@
1
+/**************
2
+ * usb_host.h *
3
+ **************/
4
+
5
+/****************************************************************************
6
+ *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
7
+ *                                                                          *
8
+ *   This program is free software: you can redistribute it and/or modify   *
9
+ *   it under the terms of the GNU General Public License as published by   *
10
+ *   the Free Software Foundation, either version 3 of the License, or      *
11
+ *   (at your option) any later version.                                    *
12
+ *                                                                          *
13
+ *   This program is distributed in the hope that it will be useful,        *
14
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
15
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
16
+ *   GNU General Public License for more details.                           *
17
+ *                                                                          *
18
+ *   To view a copy of the GNU General Public License, go to the following  *
19
+ *   location: <http://www.gnu.org/licenses/>.                              *
20
+ ****************************************************************************/
21
+
22
+#ifndef _USB_HOST_H_
23
+#define _USB_HOST_H_
24
+
25
+/* This the following comes from "lib/usbhost.h", but has been rewritten
26
+ * to use the SPI functions from Marlin's HAL */
27
+
28
+class MAX3421e {
29
+  private:
30
+    static uint8_t vbusState;
31
+    void cs();
32
+    void ncs();
33
+
34
+    uint8_t GpxHandler();
35
+    uint8_t IntHandler();
36
+
37
+  public:
38
+    bool      start();
39
+
40
+    void      regWr(uint8_t reg, uint8_t data);
41
+    uint8_t*  bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
42
+    void      gpioWr(uint8_t data);
43
+    uint8_t   regRd(uint8_t reg);
44
+    uint8_t*  bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
45
+    uint8_t   gpioRd();
46
+    bool      reset();
47
+
48
+    uint8_t   getVbusState(void)   {return vbusState;};
49
+
50
+    void busprobe();
51
+
52
+    uint8_t Task();
53
+};
54
+
55
+#define USE_MARLIN_MAX3421E
56
+
57
+#if defined(__SAM3X8E__) && !defined(ARDUINO_SAM_DUE)
58
+  #define ARDUINO_SAM_DUE // Spoof the USB library that this is a DUE
59
+#endif
60
+
61
+#endif // _USB_HOST_H_

+ 1
- 1
buildroot/share/tests/megaatmega2560_tests 파일 보기

@@ -45,7 +45,7 @@ opt_set TEMP_SENSOR_4 999
45 45
 opt_set TEMP_SENSOR_BED 1
46 46
 opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT SKEW_CORRECTION \
47 47
            EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT
48
-opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES LIGHTWEIGHT_UI \
48
+opt_enable_adv USB_FLASH_DRIVE_SUPPORT SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES LIGHTWEIGHT_UI \
49 49
                CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING BABYSTEP_XY LIN_ADVANCE NANODLP_Z_SYNC QUICK_HOME JUNCTION_DEVIATION
50 50
 exec_test $1 $2 "Probeless build of AUTO_BED_LEVELING_UBL, with lots of extruders"
51 51
 #

Loading…
취소
저장