Browse Source

General fixes for LPC1768 (#7834)

* fixed some include paths

* LPC1768: Fix Serial API

Add missing serial methods used if TX_BUFFER_SIZE is set
Change return value of HalSerial:read to match Arduino API

* LPC1768: add filters to ADC

This is to try and compensate for hardware issue and oversensitivity to noise

* LPC1768: remove the polling section of delayMicroseconds

* LPC1768: lock usb mass storage device while device accesses it.

Currently only applicable to persistent store,
The device always has priority and will unmount the sd card from the host, Windows then tries to automount again so it can look like the explorer window freezes. Linux Mint, by default, just closes the Nemo window.

* Add timeout to make sure if Serial never connects that Marlin still boots

* Remove unneeded ifdef CPU_32_BIT

In general the need for ifdef CPU_32_BIT blocks means that something is missing from the HAL API or a Platform, in this case HAL_TICKS_PER_US was missing from the AVR Platform

* LPC1768: relocate RE-ARM debug_extra_script.py
Chris Pepper 6 years ago
parent
commit
46b2773e13

+ 1
- 1
Marlin/src/HAL/HAL.h View File

@@ -29,7 +29,7 @@
29 29
 #ifndef _HAL_H
30 30
 #define _HAL_H
31 31
 
32
-#include "src/inc/SPI.h"
32
+#include "../inc/SPI.h"
33 33
 
34 34
 #ifdef __AVR__
35 35
   #include "HAL_AVR/HAL_AVR.h"

+ 1
- 0
Marlin/src/HAL/HAL_AVR/HAL_AVR.h View File

@@ -105,6 +105,7 @@ extern "C" {
105 105
 #define HAL_TIMER_RATE ((F_CPU) / 8.0)
106 106
 #define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE
107 107
 #define STEPPER_TIMER_PRESCALE INT0_PRESCALER
108
+#define HAL_TICKS_PER_US (((F_CPU) / 8) / 1000000) // Can not be of type double
108 109
 
109 110
 #define ENABLE_STEPPER_DRIVER_INTERRUPT()  SBI(TIMSK1, OCIE1A)
110 111
 #define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)

+ 42
- 3
Marlin/src/HAL/HAL_LPC1768/HAL.cpp View File

@@ -113,6 +113,7 @@ void HAL_adc_enable_channel(int pin) {
113 113
   };
114 114
 }
115 115
 
116
+uint8_t active_adc = 0;
116 117
 void HAL_adc_start_conversion(const uint8_t adc_pin) {
117 118
   if (adc_pin >= (NUM_ANALOG_INPUTS) || adc_pin_map[adc_pin].port == 0xFF) {
118 119
     usb_serial.printf("HAL: HAL_adc_start_conversion: no pinmap for %d\n", adc_pin);
@@ -121,14 +122,52 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
121 122
   LPC_ADC->ADCR &= ~0xFF;                       // Reset
122 123
   SBI(LPC_ADC->ADCR, adc_pin_map[adc_pin].adc); // Select Channel
123 124
   SBI(LPC_ADC->ADCR, 24);                       // Start conversion
125
+  active_adc = adc_pin;
124 126
 }
125 127
 
126
-bool HAL_adc_finished(void) { return LPC_ADC->ADGDR & ADC_DONE; }
128
+bool HAL_adc_finished(void) {
129
+  return LPC_ADC->ADGDR & ADC_DONE;
130
+}
131
+
132
+// possible config options if something similar is extended to more platforms.
133
+#define ADC_USE_MEDIAN_FILTER      // filter out erroneous readings
134
+#define ADC_USE_LOWPASS_FILTER     // filter out high frequency noise
135
+#define ADC_LOWPASS_K_VALUE 4      // how much to smooth out noise (1:8)
136
+
137
+struct MedianFilter {
138
+  uint16_t values[3];
139
+  uint8_t next_val;
140
+  MedianFilter() {
141
+    next_val = 0;
142
+    values[0] = values[1] = values[2] = 0;
143
+  }
144
+  uint16_t update(uint16_t value) {
145
+    values[next_val++] = value;
146
+    next_val = next_val % 3;
147
+    return max(min(values[0], values[1]), min(max(values[0], values[1]), values[2]));     //median
148
+  }
149
+};
150
+
151
+uint16_t lowpass_filter(uint16_t value) {
152
+  const uint8_t k_data_shift = ADC_LOWPASS_K_VALUE;
153
+  static uint32_t data_delay[NUM_ANALOG_INPUTS] = { 0 };
154
+  uint32_t &active_filter = data_delay[active_adc];
155
+  active_filter = active_filter - (active_filter >> k_data_shift) + value;
156
+  return (uint16_t)(active_filter >> k_data_shift);
157
+}
127 158
 
128 159
 uint16_t HAL_adc_get_result(void) {
129 160
   uint32_t data = LPC_ADC->ADGDR;
130
-  CBI(LPC_ADC->ADCR, 24);                       // Stop conversion
131
-  return (data & ADC_OVERRUN) ? 0 : (data >> 6) & 0x3FF; // 10bit
161
+  CBI(LPC_ADC->ADCR, 24);    // Stop conversion
162
+  if (data & ADC_OVERRUN) return 0;
163
+  #ifdef ADC_USE_MEDIAN_FILTER
164
+    static MedianFilter median_filter[NUM_ANALOG_INPUTS];
165
+    data = median_filter[active_adc].update((uint16_t)data);
166
+  #endif
167
+  #ifdef ADC_USE_LOWPASS_FILTER
168
+    data = lowpass_filter((uint16_t)data);
169
+  #endif
170
+  return ((data >> 6) & 0x3ff);    // 10bit
132 171
 }
133 172
 
134 173
 #define SBIT_CNTEN     0

+ 3
- 14
Marlin/src/HAL/HAL_LPC1768/arduino.cpp View File

@@ -57,20 +57,9 @@ void delayMicroseconds(uint32_t us) {
57 57
     us = us % 1000;
58 58
   }
59 59
 
60
-  if (us < 5) { // burn cycles, time in interrupts will not be taken into account
61
-    loops = us * nop_factor;
62
-    while (loops > 0) --loops;
63
-  }
64
-  else { // poll systick, more accurate through interrupts
65
-    uint32_t start = SysTick->VAL;
66
-    uint32_t load = SysTick->LOAD;
67
-    uint32_t end = start - (load / 1000) * us;
68
-
69
-    if (end >> 31)
70
-      while (!(SysTick->VAL > start && SysTick->VAL < (load + end))) __NOP();
71
-    else
72
-      while (SysTick->VAL > end) __NOP();
73
-  }
60
+  // burn cycles, time in interrupts will not be taken into account
61
+  loops = us * nop_factor;
62
+  while (loops > 0) --loops;
74 63
 }
75 64
 
76 65
 extern "C" void delay(const int msec) {

debug_extra_script.py → Marlin/src/HAL/HAL_LPC1768/debug_extra_script.py View File


+ 10
- 1
Marlin/src/HAL/HAL_LPC1768/persistent_store_impl.cpp View File

@@ -9,6 +9,9 @@
9 9
 #include "chanfs/diskio.h"
10 10
 #include "chanfs/ff.h"
11 11
 
12
+extern uint32_t MSC_Aquire_Lock();
13
+extern uint32_t MSC_Release_Lock();
14
+
12 15
 namespace HAL {
13 16
 namespace PersistentStore {
14 17
 
@@ -16,14 +19,20 @@ FATFS fat_fs;
16 19
 FIL eeprom_file;
17 20
 
18 21
 bool access_start() {
19
-  f_mount(&fat_fs, "", 1);
22
+  MSC_Aquire_Lock();
23
+  if(f_mount(&fat_fs, "", 1)){
24
+    MSC_Release_Lock();
25
+    return false;
26
+  }
20 27
   FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
28
+  if(res) MSC_Release_Lock();
21 29
   return (res == FR_OK);
22 30
 }
23 31
 
24 32
 bool access_finish() {
25 33
   f_close(&eeprom_file);
26 34
   f_unmount("");
35
+  MSC_Release_Lock();
27 36
   return true;
28 37
 }
29 38
 

+ 12
- 0
Marlin/src/HAL/HAL_LPC1768/serial.h View File

@@ -100,6 +100,7 @@ public:
100 100
   }
101 101
 
102 102
   char read() {
103
+    if(receive_buffer.empty()) return -1;
103 104
     return (char)receive_buffer.read();
104 105
   }
105 106
 
@@ -117,6 +118,17 @@ public:
117 118
   }
118 119
 
119 120
   void flush() {
121
+    receive_buffer.clear();
122
+  }
123
+
124
+  uint8_t availableForWrite(void){
125
+    return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free();
126
+  }
127
+
128
+  void flushTX(void){
129
+    if(host_connected) {
130
+      while(transmit_buffer.available());
131
+    }
120 132
   }
121 133
 
122 134
   void printf(const char *format, ...) {

+ 2
- 1
Marlin/src/Marlin.cpp View File

@@ -681,7 +681,8 @@ void setup() {
681 681
   #endif
682 682
 
683 683
   MYSERIAL.begin(BAUDRATE);
684
-  while(!MYSERIAL);
684
+  uint32_t serial_connect_timeout = millis() + 1000;
685
+  while(!MYSERIAL && PENDING(millis(), serial_connect_timeout));
685 686
   SERIAL_PROTOCOLLNPGM("start");
686 687
   SERIAL_ECHO_START();
687 688
 

+ 1
- 1
Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd.h View File

@@ -23,7 +23,7 @@
23 23
 #ifndef ULCDST7920_H
24 24
 #define ULCDST7920_H
25 25
 
26
-#include <src/Marlin.h>
26
+#include "../../Marlin.h"
27 27
 
28 28
 #if ENABLED(U8GLIB_ST7920)
29 29
 

+ 2
- 7
Marlin/src/module/stepper.cpp View File

@@ -323,13 +323,8 @@ void Stepper::isr() {
323 323
 
324 324
   HAL_TIMER_TYPE ocr_val;
325 325
 
326
-  #ifdef CPU_32_BIT
327
-    #define ENDSTOP_NOMINAL_OCR_VAL 1500 * HAL_TICKS_PER_US    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
328
-    #define OCR_VAL_TOLERANCE 500 * HAL_TICKS_PER_US           // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
329
-  #else
330
-    #define ENDSTOP_NOMINAL_OCR_VAL 3000    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
331
-    #define OCR_VAL_TOLERANCE 1000          // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
332
-  #endif
326
+  #define ENDSTOP_NOMINAL_OCR_VAL 1500 * HAL_TICKS_PER_US    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
327
+  #define OCR_VAL_TOLERANCE 500 * HAL_TICKS_PER_US           // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
333 328
 
334 329
   #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
335 330
     // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)

+ 1
- 1
frameworks/CMSIS/LPC1768/lib/LiquidCrystal.cpp View File

@@ -3,7 +3,7 @@
3 3
 #include <stdio.h>
4 4
 #include <string.h>
5 5
 #include <inttypes.h>
6
-#include "arduino.h"
6
+#include <arduino.h>
7 7
 
8 8
 // When the display powers up, it is configured as follows:
9 9
 //

+ 140
- 20
frameworks/CMSIS/LPC1768/lib/usb/mscuser.cpp View File

@@ -26,6 +26,7 @@ extern "C" {
26 26
 #include "usbhw.h"
27 27
 #include "usbcore.h"
28 28
 #include "mscuser.h"
29
+#include "lpc17xx_wdt.h"
29 30
 
30 31
 #include "../chanfs/diskio.h"
31 32
 #include <debug_frmwrk.h>
@@ -44,13 +45,71 @@ uint8_t  BulkStage;               /* Bulk Stage */
44 45
 uint8_t  BulkBuf[MSC_MAX_PACKET]; /* Bulk In/Out Buffer */
45 46
 uint8_t  block_cache[MSC_BLOCK_SIZE];
46 47
 uint8_t  BulkLen;                 /* Bulk In/Out Length */
48
+Sense sense_data;
47 49
 
48 50
 MSC_CBW CBW;                   /* Command Block Wrapper */
49 51
 MSC_CSW CSW;                   /* Command Status Wrapper */
50
-uint8_t media_lock = 0;
52
+volatile uint8_t media_lock = 0;
53
+volatile bool device_wants_lock = false;
54
+
55
+#define NO_LOCK 0
56
+#define HOST_LOCK 1
57
+#define DEVICE_LOCK 2
58
+
59
+extern uint32_t millis();
60
+extern void _delay_ms(int delay);
61
+
62
+uint32_t MSC_Aquire_Lock() {
63
+  NVIC_DisableIRQ(USB_IRQn);
64
+  device_wants_lock = true;
65
+  uint32_t end_millis = millis() + 1000;
66
+  if(media_lock == HOST_LOCK) {
67
+    NVIC_EnableIRQ(USB_IRQn);
68
+    while(media_lock == HOST_LOCK) {
69
+      if(((long)(end_millis - (millis())) < 0)) {
70
+        _DBG("No signal from Host, Assume success\n");
71
+        break;
72
+      }
73
+      WDT_Feed();
74
+    }
75
+  }
76
+  NVIC_DisableIRQ(USB_IRQn);
77
+  media_lock = DEVICE_LOCK;
78
+  NVIC_EnableIRQ(USB_IRQn);
79
+  _DBG("Device MSC Lock\n");
80
+  device_wants_lock = false;
81
+  return 0;
82
+}
83
+
84
+uint32_t MSC_Release_Lock() {
85
+  if(media_lock != DEVICE_LOCK) {
86
+    return 0; // Didn't have lock
87
+  }
88
+  media_lock = NO_LOCK;
89
+  if(disk_status(0) != STA_NOINIT) disk_ioctl(0, GET_SECTOR_COUNT, (void *)(&MSC_BlockCount));
90
+  _DBG("Device MSC Unlock\n");
91
+  NVIC_DisableIRQ(USB_IRQn);
92
+  sense_data.set(Sense_KEY::UNIT_ATTENTION, Sense_ASC::MEDIA_CHANGED);
93
+  NVIC_EnableIRQ(USB_IRQn);
94
+  return 0;   // Released
95
+}
51 96
 
52 97
 uint32_t MSC_SD_Lock() {
53
-  media_lock = CBW.CB[4]; //0x1 - lock, 0x0 - unlock
98
+  if(media_lock == DEVICE_LOCK || (device_wants_lock && CBW.CB[4])) {
99
+    CSW.bStatus = CSW_CMD_FAILED;
100
+    sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::LOGICAL_UNIT_NOT_READY, Sense_ASCQ::DEVICE_IS_BUSY);
101
+    MSC_SetCSW();
102
+    _DBG("Device has Lock (or is waiting for lock) cannot Lock..\n");
103
+    return 1;
104
+  }
105
+
106
+  if(CBW.CB[4]) {
107
+    media_lock = HOST_LOCK;
108
+    _DBG("OS MSC Lock\n");
109
+  } else {
110
+    media_lock = NO_LOCK;
111
+    _DBG("OS MSC Unlock\n");
112
+  }
54 113
   // logical_unit = CBW.CB[1] & 0xE0;
55 114
   CSW.bStatus = CSW_CMD_PASSED;
56 115
   MSC_SetCSW();
@@ -78,20 +137,28 @@ void MSC_StartStopUnit() {
78 137
   switch (CBW.CB[4] & 0x03) {
79 138
     case STARTSTOP_EJECT:
80 139
       MSC_SD_Release(0);
140
+      media_lock = NO_LOCK;
141
+      _DBG("OS Media Ejected UNLOCK\n");
81 142
       break;
82 143
     case STARTSTOP_LOAD:
83 144
       if(MSC_BlockCount == 0) {
84 145
         if(MSC_SD_Init(0) != 0) {
85 146
           CSW.bStatus = CSW_CMD_FAILED;
147
+          sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::MANUAL_INTERVENTION_REQUIRED);
86 148
           MSC_SetCSW();
87 149
           return;
88 150
         }
89 151
       }
152
+      media_lock = HOST_LOCK;
153
+      _DBG("OS Media Mount LOCKED\n");
90 154
       break;
91 155
     default:
92
-      _DBG("MSC_StartStopUnit unknown startstopunit sub command\n");
156
+      _DBG("MSC_StartStopUnit unknown startstopunit sub command: ");
157
+      _DBH(CBW.CB[4] & 0x03);
158
+      _DBG("\n");
93 159
   }
94 160
   CSW.bStatus = CSW_CMD_PASSED;
161
+  sense_data.reset();
95 162
   MSC_SetCSW();
96 163
 }
97 164
 
@@ -122,6 +189,18 @@ uint32_t MSC_GetMaxLUN (void) {
122 189
 }
123 190
 
124 191
 
192
+bool host_get_lock(void) {
193
+  if(media_lock != DEVICE_LOCK && !device_wants_lock) {
194
+    media_lock = HOST_LOCK;
195
+    return true;
196
+  } else {
197
+    CSW.bStatus = CSW_CMD_FAILED;
198
+    sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::LOGICAL_UNIT_NOT_READY, Sense_ASCQ::DEVICE_IS_BUSY);
199
+    MSC_SetCSW();
200
+    return false;
201
+  }
202
+}
203
+
125 204
 /*
126 205
  *  MSC Memory Read Callback
127 206
  *   Called automatically on Memory Read Event
@@ -130,6 +209,12 @@ uint32_t MSC_GetMaxLUN (void) {
130 209
  */
131 210
 
132 211
 void MSC_MemoryRead (void) {
212
+  if(!host_get_lock()) {
213
+     _DBG("Auto Lock Fail Permission Denied Device has Lock\n");
214
+     return;
215
+  }
216
+  WDT_Feed();
217
+
133 218
   uint32_t n = (length > MSC_MAX_PACKET) ? MSC_MAX_PACKET : length;
134 219
 
135 220
   if (lba > MSC_BlockCount) {
@@ -158,6 +243,7 @@ void MSC_MemoryRead (void) {
158 243
 
159 244
   if (BulkStage != MSC_BS_DATA_IN) {
160 245
     CSW.bStatus = CSW_CMD_PASSED;
246
+    sense_data.reset();
161 247
   }
162 248
 }
163 249
 
@@ -170,6 +256,11 @@ void MSC_MemoryRead (void) {
170 256
  */
171 257
 
172 258
 void MSC_MemoryWrite (void) {
259
+  if(!host_get_lock()) {
260
+     _DBG("Auto Lock Fail Permission Denied Device has Lock\n");
261
+     return;
262
+  }
263
+  WDT_Feed();
173 264
 
174 265
   for (uint32_t n = 0; n < BulkLen; n++) {
175 266
     block_cache[block_offset + n] = BulkBuf[n];
@@ -192,6 +283,7 @@ void MSC_MemoryWrite (void) {
192 283
 
193 284
   if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
194 285
     CSW.bStatus = CSW_CMD_PASSED;
286
+    sense_data.reset();
195 287
     MSC_SetCSW();
196 288
   }
197 289
 }
@@ -205,6 +297,11 @@ void MSC_MemoryWrite (void) {
205 297
  */
206 298
 
207 299
 void MSC_MemoryVerify (void) {
300
+  if(!host_get_lock()) {
301
+     _DBG("Auto Lock Fail Permission Denied Device has Lock\n");
302
+     return;
303
+  }
304
+  WDT_Feed();
208 305
 
209 306
   if(!block_offset) {
210 307
     disk_read(0, block_cache, lba, 1);
@@ -222,7 +319,13 @@ void MSC_MemoryVerify (void) {
222 319
   CSW.dDataResidue -= BulkLen;
223 320
 
224 321
   if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
225
-    CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;
322
+    if(MemOK) {
323
+      CSW.bStatus = CSW_CMD_PASSED;
324
+      sense_data.reset();
325
+    } else {
326
+      CSW.bStatus = CSW_CMD_FAILED;
327
+      sense_data.set(Sense_KEY::MEDIUM_ERROR);
328
+    }
226 329
     MSC_SetCSW();
227 330
   }
228 331
 }
@@ -321,10 +424,15 @@ void MSC_TestUnitReady (void) {
321 424
     }
322 425
   }
323 426
 
324
-  if(MSC_BlockCount > 0) {
427
+  if(device_wants_lock) {
428
+    sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::REASON_UNKNOWN);
429
+    CSW.bStatus = CSW_CMD_FAILED;
430
+  } else if(MSC_BlockCount > 0) {
431
+    sense_data.reset();
325 432
     CSW.bStatus = CSW_CMD_PASSED;
326 433
   } else {
327 434
     CSW.bStatus = CSW_CMD_FAILED;
435
+    sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::LOADABLE);
328 436
   }
329 437
 
330 438
   MSC_SetCSW();
@@ -341,9 +449,13 @@ void MSC_RequestSense (void) {
341 449
 
342 450
   if (!DataInFormat()) return;
343 451
 
452
+  if(media_lock == DEVICE_LOCK || device_wants_lock) {
453
+    sense_data.set(Sense_KEY::NOT_READY, Sense_ASC::MEDIUM_NOT_PRESENT, Sense_ASCQ::REASON_UNKNOWN);
454
+  }
455
+
344 456
   BulkBuf[ 0] = 0x70;          /* Response Code */
345 457
   BulkBuf[ 1] = 0x00;
346
-  BulkBuf[ 2] = static_cast<uint8_t>(Sense_KEY::ILLEGAL_REQUEST);
458
+  BulkBuf[ 2] = static_cast<uint8_t>(sense_data.key);
347 459
   BulkBuf[ 3] = 0x00;
348 460
   BulkBuf[ 4] = 0x00;
349 461
   BulkBuf[ 5] = 0x00;
@@ -354,17 +466,17 @@ void MSC_RequestSense (void) {
354 466
   BulkBuf[ 9] = 0x00;
355 467
   BulkBuf[10] = 0x00;
356 468
   BulkBuf[11] = 0x00;
357
-  BulkBuf[12] = static_cast<uint8_t>(Sense_ASC::CANNOT_READ_MEDIUM);
358
-  BulkBuf[13] = static_cast<uint8_t>(Sense_ASCQ::UNKNOWN_FORMAT);
469
+  BulkBuf[12] = static_cast<uint8_t>(sense_data.asc);
470
+  BulkBuf[13] = static_cast<uint8_t>(sense_data.ascq);
359 471
   BulkBuf[14] = 0x00;
360 472
   BulkBuf[15] = 0x00;
361 473
   BulkBuf[16] = 0x00;
362 474
   BulkBuf[17] = 0x00;
363 475
 
364
-  if (MSC_BlockCount == 0) {
365
-    BulkBuf[ 2] = static_cast<uint8_t>(Sense_KEY::NOT_READY);
366
-    BulkBuf[12] = static_cast<uint8_t>(Sense_ASC::MEDIUM_NOT_PRESENT);
367
-    BulkBuf[13] = static_cast<uint8_t>(Sense_ASCQ::LOADABLE);
476
+  if(sense_data.has_sense()){
477
+    _DBG("Sent Response to SenseRequest: ");
478
+    _DBH(static_cast<uint8_t>(sense_data.key));
479
+    _DBG("\n");
368 480
   }
369 481
 
370 482
   BulkLen = 18;
@@ -423,10 +535,6 @@ void MSC_Inquiry (void) {
423 535
   BulkBuf[34] = '0';
424 536
   BulkBuf[35] = ' ';
425 537
 
426
-  if(MSC_BlockCount == 0) {
427
-    BulkBuf[0] = 0x20; // Direct Access Device usually available but not currently
428
-  }
429
-
430 538
   BulkLen = 36;
431 539
   DataInTransfer();
432 540
 }
@@ -553,8 +661,9 @@ void MSC_GetCBW (void) {
553 661
     CSW.dDataResidue = CBW.dDataLength;
554 662
     if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) {
555 663
 fail: CSW.bStatus = CSW_CMD_FAILED;
664
+      sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
556 665
       MSC_SetCSW();
557
-      _DBG("Failed SCSI OP code ");
666
+      _DBG("Unsupported SCSI OP code ");
558 667
       _DBH(CBW.CB[0]);
559 668
       _DBG("\n");
560 669
     } else {
@@ -627,6 +736,20 @@ fail: CSW.bStatus = CSW_CMD_FAILED;
627 736
             }
628 737
           }
629 738
           break;
739
+        case 0x35: // SCSI_SYNCHRONIZECACHE10
740
+          _DBG("SCSI_SYNCHRONIZECACHE10 Unsupported\n");
741
+          CSW.bStatus = CSW_CMD_FAILED;
742
+          sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
743
+          MSC_SetCSW();
744
+          break;
745
+        case 0x9E: // SCSI_SERVICEACTIONIN16
746
+          _DBG("ServiceAction(16) Action: ");
747
+          _DBH(CBW.CB[1]);
748
+          _DBG(" Unsupported\n");
749
+          CSW.bStatus = CSW_CMD_FAILED;
750
+          sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
751
+          MSC_SetCSW();
752
+          break;
630 753
         default:
631 754
           goto fail;
632 755
       }
@@ -647,7 +770,6 @@ fail: CSW.bStatus = CSW_CMD_FAILED;
647 770
  */
648 771
 
649 772
 void MSC_SetCSW (void) {
650
-
651 773
   CSW.dSignature = MSC_CSW_Signature;
652 774
   USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
653 775
   BulkStage = MSC_BS_CSW;
@@ -661,7 +783,6 @@ void MSC_SetCSW (void) {
661 783
  */
662 784
 
663 785
 void MSC_BulkIn (void) {
664
-
665 786
   switch (BulkStage) {
666 787
     case MSC_BS_DATA_IN:
667 788
       switch (CBW.CB[0]) {
@@ -691,7 +812,6 @@ void MSC_BulkIn (void) {
691 812
  */
692 813
 
693 814
 void MSC_BulkOut (void) {
694
-
695 815
   BulkLen = (uint8_t)USB_ReadEP(MSC_EP_OUT, BulkBuf);
696 816
   switch (BulkStage) {
697 817
     case MSC_BS_CBW:

+ 41
- 6
frameworks/CMSIS/LPC1768/lib/usb/mscuser.h View File

@@ -38,7 +38,7 @@ extern void MSC_SetCSW (void);
38 38
 extern void MSC_BulkIn (void);
39 39
 extern void MSC_BulkOut(void);
40 40
 
41
-enum class Sense_KEY : uint8_t {
41
+enum struct Sense_KEY : uint8_t {
42 42
   NO_SENSE,
43 43
   RECOVERED_ERROR,
44 44
   NOT_READY,
@@ -49,15 +49,25 @@ enum class Sense_KEY : uint8_t {
49 49
   DATA_PROTECT
50 50
 };
51 51
 
52
-enum class Sense_ASC : uint8_t {
52
+enum struct Sense_ASC : uint8_t {
53
+  NONE = 0x0,
54
+  LOGICAL_UNIT_NOT_READY = 0x04,
53 55
   CANNOT_READ_MEDIUM = 0x30,
54
-  MEDIUM_NOT_PRESENT = 0x3A
56
+  MEDIUM_NOT_PRESENT = 0x3A,
57
+  MEDIA_CHANGED = 0x28
55 58
 };
56 59
 
57
-enum class Sense_ASCQ : uint8_t {
58
-  // CANNOT_READ_MEDIUM
60
+enum struct Sense_ASCQ : uint8_t {
61
+  // ASC: LOGICAL_UNIT_NOT_READY
62
+  CAUSE_NOT_REPORTABLE = 0x00,
63
+  UNIT_IS_IN_PROCESS_OF_BECOMING_READY,
64
+  INITIALIZING_COMMAND_REQUIRED,
65
+  MANUAL_INTERVENTION_REQUIRED,
66
+  FORMAT_IN_PROGRESS,
67
+  DEVICE_IS_BUSY = 0xFF,
68
+  // ASC: CANNOT_READ_MEDIUM
59 69
   UNKNOWN_FORMAT = 0x01,
60
-  // MEDIUM_NOT_PRESENT
70
+  // ASC: MEDIUM_NOT_PRESENT
61 71
   REASON_UNKNOWN = 0x00,
62 72
   TRAY_CLOSED,
63 73
   TRAY_OPEN,
@@ -65,5 +75,30 @@ enum class Sense_ASCQ : uint8_t {
65 75
   AUXILIARY_MEMORY_ACCESSIBLE
66 76
 };
67 77
 
78
+struct Sense {
79
+  Sense() {
80
+    reset();
81
+  }
82
+
83
+  void set(Sense_KEY key_val, Sense_ASC asc_val = Sense_ASC::NONE, Sense_ASCQ ascq_val = Sense_ASCQ::REASON_UNKNOWN) {
84
+    key = key_val;
85
+    asc = asc_val;
86
+    ascq = ascq_val;
87
+  }
88
+
89
+  void reset() {
90
+    key = Sense_KEY::NO_SENSE;
91
+    asc = Sense_ASC::NONE;
92
+    ascq = Sense_ASCQ::REASON_UNKNOWN;
93
+  }
94
+
95
+  bool has_sense() {
96
+    return key != Sense_KEY::NO_SENSE;
97
+  }
98
+
99
+  Sense_KEY key;
100
+  Sense_ASC asc;
101
+  Sense_ASCQ ascq;
102
+};
68 103
 
69 104
 #endif  /* __MSCUSER_H__ */

+ 12
- 11
platformio.ini View File

@@ -158,17 +158,18 @@ src_filter      = ${common.default_src_filter}
158 158
 #
159 159
 [env:Re-ARM_debug_and_upload]
160 160
 # Segger JLink
161
-platform      = nxplpc
162
-#framework    = mbed
163
-board         = lpc1768
164
-board_f_cpu   = 100000000L
165
-build_flags   = !python Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
166
-lib_ldf_mode  = off
167
-lib_deps      = U8glib-ARM
168
-src_filter    = ${common.default_src_filter}
169
-extra_scripts = debug_extra_script.py, Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
170
-debug_tool    = custom
171
-debug_server  =
161
+platform       = nxplpc
162
+#framework     = mbed
163
+board          = lpc1768
164
+board_f_cpu    = 100000000L
165
+build_flags    = !python Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
166
+lib_ldf_mode   = off
167
+lib_extra_dirs = frameworks
168
+lib_deps       = U8glib-ARM, CMSIS-LPC1768
169
+src_filter     = ${common.default_src_filter}
170
+extra_scripts  =  Marlin/src/HAL/HAL_LPC1768/debug_extra_script.py, Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
171
+debug_tool     = custom
172
+debug_server   =
172 173
   C:\Program Files (x86)\SEGGER\JLink_V618d\JLinkGDBServerCL.exe
173 174
   -select
174 175
   USB

Loading…
Cancel
Save