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
 #ifndef _HAL_H
29
 #ifndef _HAL_H
30
 #define _HAL_H
30
 #define _HAL_H
31
 
31
 
32
-#include "src/inc/SPI.h"
32
+#include "../inc/SPI.h"
33
 
33
 
34
 #ifdef __AVR__
34
 #ifdef __AVR__
35
   #include "HAL_AVR/HAL_AVR.h"
35
   #include "HAL_AVR/HAL_AVR.h"

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

105
 #define HAL_TIMER_RATE ((F_CPU) / 8.0)
105
 #define HAL_TIMER_RATE ((F_CPU) / 8.0)
106
 #define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE
106
 #define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE
107
 #define STEPPER_TIMER_PRESCALE INT0_PRESCALER
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
 #define ENABLE_STEPPER_DRIVER_INTERRUPT()  SBI(TIMSK1, OCIE1A)
110
 #define ENABLE_STEPPER_DRIVER_INTERRUPT()  SBI(TIMSK1, OCIE1A)
110
 #define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
111
 #define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)

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

113
   };
113
   };
114
 }
114
 }
115
 
115
 
116
+uint8_t active_adc = 0;
116
 void HAL_adc_start_conversion(const uint8_t adc_pin) {
117
 void HAL_adc_start_conversion(const uint8_t adc_pin) {
117
   if (adc_pin >= (NUM_ANALOG_INPUTS) || adc_pin_map[adc_pin].port == 0xFF) {
118
   if (adc_pin >= (NUM_ANALOG_INPUTS) || adc_pin_map[adc_pin].port == 0xFF) {
118
     usb_serial.printf("HAL: HAL_adc_start_conversion: no pinmap for %d\n", adc_pin);
119
     usb_serial.printf("HAL: HAL_adc_start_conversion: no pinmap for %d\n", adc_pin);
121
   LPC_ADC->ADCR &= ~0xFF;                       // Reset
122
   LPC_ADC->ADCR &= ~0xFF;                       // Reset
122
   SBI(LPC_ADC->ADCR, adc_pin_map[adc_pin].adc); // Select Channel
123
   SBI(LPC_ADC->ADCR, adc_pin_map[adc_pin].adc); // Select Channel
123
   SBI(LPC_ADC->ADCR, 24);                       // Start conversion
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
 uint16_t HAL_adc_get_result(void) {
159
 uint16_t HAL_adc_get_result(void) {
129
   uint32_t data = LPC_ADC->ADGDR;
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
 #define SBIT_CNTEN     0
173
 #define SBIT_CNTEN     0

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

57
     us = us % 1000;
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
 extern "C" void delay(const int msec) {
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
 #include "chanfs/diskio.h"
9
 #include "chanfs/diskio.h"
10
 #include "chanfs/ff.h"
10
 #include "chanfs/ff.h"
11
 
11
 
12
+extern uint32_t MSC_Aquire_Lock();
13
+extern uint32_t MSC_Release_Lock();
14
+
12
 namespace HAL {
15
 namespace HAL {
13
 namespace PersistentStore {
16
 namespace PersistentStore {
14
 
17
 
16
 FIL eeprom_file;
19
 FIL eeprom_file;
17
 
20
 
18
 bool access_start() {
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
   FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
27
   FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
28
+  if(res) MSC_Release_Lock();
21
   return (res == FR_OK);
29
   return (res == FR_OK);
22
 }
30
 }
23
 
31
 
24
 bool access_finish() {
32
 bool access_finish() {
25
   f_close(&eeprom_file);
33
   f_close(&eeprom_file);
26
   f_unmount("");
34
   f_unmount("");
35
+  MSC_Release_Lock();
27
   return true;
36
   return true;
28
 }
37
 }
29
 
38
 

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

100
   }
100
   }
101
 
101
 
102
   char read() {
102
   char read() {
103
+    if(receive_buffer.empty()) return -1;
103
     return (char)receive_buffer.read();
104
     return (char)receive_buffer.read();
104
   }
105
   }
105
 
106
 
117
   }
118
   }
118
 
119
 
119
   void flush() {
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
   void printf(const char *format, ...) {
134
   void printf(const char *format, ...) {

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

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

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

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

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

323
 
323
 
324
   HAL_TIMER_TYPE ocr_val;
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
   #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
329
   #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
335
     // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
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
 #include <stdio.h>
3
 #include <stdio.h>
4
 #include <string.h>
4
 #include <string.h>
5
 #include <inttypes.h>
5
 #include <inttypes.h>
6
-#include "arduino.h"
6
+#include <arduino.h>
7
 
7
 
8
 // When the display powers up, it is configured as follows:
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
 #include "usbhw.h"
26
 #include "usbhw.h"
27
 #include "usbcore.h"
27
 #include "usbcore.h"
28
 #include "mscuser.h"
28
 #include "mscuser.h"
29
+#include "lpc17xx_wdt.h"
29
 
30
 
30
 #include "../chanfs/diskio.h"
31
 #include "../chanfs/diskio.h"
31
 #include <debug_frmwrk.h>
32
 #include <debug_frmwrk.h>
44
 uint8_t  BulkBuf[MSC_MAX_PACKET]; /* Bulk In/Out Buffer */
45
 uint8_t  BulkBuf[MSC_MAX_PACKET]; /* Bulk In/Out Buffer */
45
 uint8_t  block_cache[MSC_BLOCK_SIZE];
46
 uint8_t  block_cache[MSC_BLOCK_SIZE];
46
 uint8_t  BulkLen;                 /* Bulk In/Out Length */
47
 uint8_t  BulkLen;                 /* Bulk In/Out Length */
48
+Sense sense_data;
47
 
49
 
48
 MSC_CBW CBW;                   /* Command Block Wrapper */
50
 MSC_CBW CBW;                   /* Command Block Wrapper */
49
 MSC_CSW CSW;                   /* Command Status Wrapper */
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
 uint32_t MSC_SD_Lock() {
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
   // logical_unit = CBW.CB[1] & 0xE0;
113
   // logical_unit = CBW.CB[1] & 0xE0;
55
   CSW.bStatus = CSW_CMD_PASSED;
114
   CSW.bStatus = CSW_CMD_PASSED;
56
   MSC_SetCSW();
115
   MSC_SetCSW();
78
   switch (CBW.CB[4] & 0x03) {
137
   switch (CBW.CB[4] & 0x03) {
79
     case STARTSTOP_EJECT:
138
     case STARTSTOP_EJECT:
80
       MSC_SD_Release(0);
139
       MSC_SD_Release(0);
140
+      media_lock = NO_LOCK;
141
+      _DBG("OS Media Ejected UNLOCK\n");
81
       break;
142
       break;
82
     case STARTSTOP_LOAD:
143
     case STARTSTOP_LOAD:
83
       if(MSC_BlockCount == 0) {
144
       if(MSC_BlockCount == 0) {
84
         if(MSC_SD_Init(0) != 0) {
145
         if(MSC_SD_Init(0) != 0) {
85
           CSW.bStatus = CSW_CMD_FAILED;
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
           MSC_SetCSW();
148
           MSC_SetCSW();
87
           return;
149
           return;
88
         }
150
         }
89
       }
151
       }
152
+      media_lock = HOST_LOCK;
153
+      _DBG("OS Media Mount LOCKED\n");
90
       break;
154
       break;
91
     default:
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
   CSW.bStatus = CSW_CMD_PASSED;
160
   CSW.bStatus = CSW_CMD_PASSED;
161
+  sense_data.reset();
95
   MSC_SetCSW();
162
   MSC_SetCSW();
96
 }
163
 }
97
 
164
 
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
  *  MSC Memory Read Callback
205
  *  MSC Memory Read Callback
127
  *   Called automatically on Memory Read Event
206
  *   Called automatically on Memory Read Event
130
  */
209
  */
131
 
210
 
132
 void MSC_MemoryRead (void) {
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
   uint32_t n = (length > MSC_MAX_PACKET) ? MSC_MAX_PACKET : length;
218
   uint32_t n = (length > MSC_MAX_PACKET) ? MSC_MAX_PACKET : length;
134
 
219
 
135
   if (lba > MSC_BlockCount) {
220
   if (lba > MSC_BlockCount) {
158
 
243
 
159
   if (BulkStage != MSC_BS_DATA_IN) {
244
   if (BulkStage != MSC_BS_DATA_IN) {
160
     CSW.bStatus = CSW_CMD_PASSED;
245
     CSW.bStatus = CSW_CMD_PASSED;
246
+    sense_data.reset();
161
   }
247
   }
162
 }
248
 }
163
 
249
 
170
  */
256
  */
171
 
257
 
172
 void MSC_MemoryWrite (void) {
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
   for (uint32_t n = 0; n < BulkLen; n++) {
265
   for (uint32_t n = 0; n < BulkLen; n++) {
175
     block_cache[block_offset + n] = BulkBuf[n];
266
     block_cache[block_offset + n] = BulkBuf[n];
192
 
283
 
193
   if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
284
   if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
194
     CSW.bStatus = CSW_CMD_PASSED;
285
     CSW.bStatus = CSW_CMD_PASSED;
286
+    sense_data.reset();
195
     MSC_SetCSW();
287
     MSC_SetCSW();
196
   }
288
   }
197
 }
289
 }
205
  */
297
  */
206
 
298
 
207
 void MSC_MemoryVerify (void) {
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
   if(!block_offset) {
306
   if(!block_offset) {
210
     disk_read(0, block_cache, lba, 1);
307
     disk_read(0, block_cache, lba, 1);
222
   CSW.dDataResidue -= BulkLen;
319
   CSW.dDataResidue -= BulkLen;
223
 
320
 
224
   if ((length == 0) || (BulkStage == MSC_BS_CSW)) {
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
     MSC_SetCSW();
329
     MSC_SetCSW();
227
   }
330
   }
228
 }
331
 }
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
     CSW.bStatus = CSW_CMD_PASSED;
432
     CSW.bStatus = CSW_CMD_PASSED;
326
   } else {
433
   } else {
327
     CSW.bStatus = CSW_CMD_FAILED;
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
   MSC_SetCSW();
438
   MSC_SetCSW();
341
 
449
 
342
   if (!DataInFormat()) return;
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
   BulkBuf[ 0] = 0x70;          /* Response Code */
456
   BulkBuf[ 0] = 0x70;          /* Response Code */
345
   BulkBuf[ 1] = 0x00;
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
   BulkBuf[ 3] = 0x00;
459
   BulkBuf[ 3] = 0x00;
348
   BulkBuf[ 4] = 0x00;
460
   BulkBuf[ 4] = 0x00;
349
   BulkBuf[ 5] = 0x00;
461
   BulkBuf[ 5] = 0x00;
354
   BulkBuf[ 9] = 0x00;
466
   BulkBuf[ 9] = 0x00;
355
   BulkBuf[10] = 0x00;
467
   BulkBuf[10] = 0x00;
356
   BulkBuf[11] = 0x00;
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
   BulkBuf[14] = 0x00;
471
   BulkBuf[14] = 0x00;
360
   BulkBuf[15] = 0x00;
472
   BulkBuf[15] = 0x00;
361
   BulkBuf[16] = 0x00;
473
   BulkBuf[16] = 0x00;
362
   BulkBuf[17] = 0x00;
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
   BulkLen = 18;
482
   BulkLen = 18;
423
   BulkBuf[34] = '0';
535
   BulkBuf[34] = '0';
424
   BulkBuf[35] = ' ';
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
   BulkLen = 36;
538
   BulkLen = 36;
431
   DataInTransfer();
539
   DataInTransfer();
432
 }
540
 }
553
     CSW.dDataResidue = CBW.dDataLength;
661
     CSW.dDataResidue = CBW.dDataLength;
554
     if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) {
662
     if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) {
555
 fail: CSW.bStatus = CSW_CMD_FAILED;
663
 fail: CSW.bStatus = CSW_CMD_FAILED;
664
+      sense_data.set(Sense_KEY::ILLEGAL_REQUEST);
556
       MSC_SetCSW();
665
       MSC_SetCSW();
557
-      _DBG("Failed SCSI OP code ");
666
+      _DBG("Unsupported SCSI OP code ");
558
       _DBH(CBW.CB[0]);
667
       _DBH(CBW.CB[0]);
559
       _DBG("\n");
668
       _DBG("\n");
560
     } else {
669
     } else {
627
             }
736
             }
628
           }
737
           }
629
           break;
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
         default:
753
         default:
631
           goto fail;
754
           goto fail;
632
       }
755
       }
647
  */
770
  */
648
 
771
 
649
 void MSC_SetCSW (void) {
772
 void MSC_SetCSW (void) {
650
-
651
   CSW.dSignature = MSC_CSW_Signature;
773
   CSW.dSignature = MSC_CSW_Signature;
652
   USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
774
   USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
653
   BulkStage = MSC_BS_CSW;
775
   BulkStage = MSC_BS_CSW;
661
  */
783
  */
662
 
784
 
663
 void MSC_BulkIn (void) {
785
 void MSC_BulkIn (void) {
664
-
665
   switch (BulkStage) {
786
   switch (BulkStage) {
666
     case MSC_BS_DATA_IN:
787
     case MSC_BS_DATA_IN:
667
       switch (CBW.CB[0]) {
788
       switch (CBW.CB[0]) {
691
  */
812
  */
692
 
813
 
693
 void MSC_BulkOut (void) {
814
 void MSC_BulkOut (void) {
694
-
695
   BulkLen = (uint8_t)USB_ReadEP(MSC_EP_OUT, BulkBuf);
815
   BulkLen = (uint8_t)USB_ReadEP(MSC_EP_OUT, BulkBuf);
696
   switch (BulkStage) {
816
   switch (BulkStage) {
697
     case MSC_BS_CBW:
817
     case MSC_BS_CBW:

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

38
 extern void MSC_BulkIn (void);
38
 extern void MSC_BulkIn (void);
39
 extern void MSC_BulkOut(void);
39
 extern void MSC_BulkOut(void);
40
 
40
 
41
-enum class Sense_KEY : uint8_t {
41
+enum struct Sense_KEY : uint8_t {
42
   NO_SENSE,
42
   NO_SENSE,
43
   RECOVERED_ERROR,
43
   RECOVERED_ERROR,
44
   NOT_READY,
44
   NOT_READY,
49
   DATA_PROTECT
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
   CANNOT_READ_MEDIUM = 0x30,
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
   UNKNOWN_FORMAT = 0x01,
69
   UNKNOWN_FORMAT = 0x01,
60
-  // MEDIUM_NOT_PRESENT
70
+  // ASC: MEDIUM_NOT_PRESENT
61
   REASON_UNKNOWN = 0x00,
71
   REASON_UNKNOWN = 0x00,
62
   TRAY_CLOSED,
72
   TRAY_CLOSED,
63
   TRAY_OPEN,
73
   TRAY_OPEN,
65
   AUXILIARY_MEMORY_ACCESSIBLE
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
 #endif  /* __MSCUSER_H__ */
104
 #endif  /* __MSCUSER_H__ */

+ 12
- 11
platformio.ini View File

158
 #
158
 #
159
 [env:Re-ARM_debug_and_upload]
159
 [env:Re-ARM_debug_and_upload]
160
 # Segger JLink
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
   C:\Program Files (x86)\SEGGER\JLink_V618d\JLinkGDBServerCL.exe
173
   C:\Program Files (x86)\SEGGER\JLink_V618d\JLinkGDBServerCL.exe
173
   -select
174
   -select
174
   USB
175
   USB

Loading…
Cancel
Save