Procházet zdrojové kódy

Improved Sw SPI on DUE HAL a bit more.

Now the USB MSD can transfer at 750k/s. Previously, it was 500k/s. I think this is the maximum achievable speed using Sw SPI.
etagle před 7 roky
rodič
revize
729a9f55fc

+ 251
- 76
Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp Zobrazit soubor

@@ -111,6 +111,9 @@
111 111
   #define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000) / 1000)
112 112
 
113 113
   typedef uint8_t (*pfnSpiTransfer) (uint8_t b);
114
+  typedef void    (*pfnSpiRxBlock)(uint8_t* buf, uint32_t nbyte);
115
+  typedef void    (*pfnSpiTxBlock)(const uint8_t* buf, uint32_t nbyte);
116
+
114 117
 
115 118
   /* ---------------- Macros to be able to access definitions from asm */
116 119
 
@@ -183,26 +186,32 @@
183 186
       /* Bit 0 */
184 187
       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */
185 188
       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
186
-      " nop"  "\n\t"
189
+      " nop" "\n\t"                                             /* Result will be 0 */
187 190
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
188 191
 
189
-      : [mosi_mask]"+r"( MOSI_MASK ),
190
-        [mosi_port]"+r"( MOSI_PORT_PLUS30 ),
191
-        [sck_mask]"+r"( SCK_MASK ),
192
-        [sck_port]"+r"( SCK_PORT_PLUS30 ),
193
-        [idx]"+r"( idx ),
194
-        [txval]"+r"( bout )
195
-      :
192
+      : [idx]"+r"( idx )
193
+      : [txval]"r"( bout ) ,
194
+        [mosi_mask]"r"( MOSI_MASK ),
195
+        [mosi_port]"r"( MOSI_PORT_PLUS30 ),
196
+        [sck_mask]"r"( SCK_MASK ),
197
+        [sck_port]"r"( SCK_PORT_PLUS30 )
196 198
       : "cc"
197 199
     );
198 200
 
199 201
     return 0;
200 202
   }
201 203
 
204
+ // Calculates the bit band alias address and returns a pointer address to word.
205
+ // addr: The byte address of bitbanding bit.
206
+ // bit:  The bit position of bitbanding bit.
207
+#define BITBAND_ADDRESS(addr, bit) \
208
+    (((uint32_t)(addr) & 0xF0000000) + 0x02000000 + ((uint32_t)(addr)&0xFFFFF)*32 + (bit)*4)
209
+
202 210
   // run at ~8 .. ~10Mhz - Rx version (Tx line not altered)
203 211
   static uint8_t spiTransferRx0(uint8_t bout) { // using Mode 0
204
-    int bin = 0, work = 0;
205
-    register uint32_t MISO_PORT_PLUS3C = ((uint32_t) PORT(MISO_PIN)) + 0x3C;  /* PDSR of port */
212
+    register uint32_t bin;
213
+    register uint32_t work;
214
+    register uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN));  /* PDSR of port in bitband area */
206 215
     register uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30;    /* SODR of port */
207 216
     register uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
208 217
     UNUSED(bout);
@@ -213,70 +222,61 @@
213 222
 
214 223
       /* bit 7 */
215 224
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
216
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
225
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
217 226
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
218
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
219
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
227
+      " bfi %[bin],%[work],#7,#1" "\n\t"                /* Store read bit as the bit 7 */
220 228
 
221 229
       /* bit 6 */
222 230
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
223
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
231
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
224 232
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
225
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
226
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
233
+      " bfi %[bin],%[work],#6,#1" "\n\t"                /* Store read bit as the bit 6 */
227 234
 
228 235
       /* bit 5 */
229 236
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
230
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
237
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
231 238
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
232
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
233
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
239
+      " bfi %[bin],%[work],#5,#1" "\n\t"                /* Store read bit as the bit 5 */
234 240
 
235 241
       /* bit 4 */
236 242
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
237
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
243
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
238 244
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
239
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
240
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
245
+      " bfi %[bin],%[work],#4,#1" "\n\t"                /* Store read bit as the bit 4 */
241 246
 
242 247
       /* bit 3 */
243 248
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
244
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
249
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
245 250
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
246
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
247
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
251
+      " bfi %[bin],%[work],#3,#1" "\n\t"                /* Store read bit as the bit 3 */
248 252
 
249 253
       /* bit 2 */
250 254
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
251
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
255
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
252 256
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
253
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
254
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
257
+      " bfi %[bin],%[work],#2,#1" "\n\t"                /* Store read bit as the bit 2 */
255 258
 
256 259
       /* bit 1 */
257 260
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
258
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
261
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
259 262
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
260
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
261
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
263
+      " bfi %[bin],%[work],#1,#1" "\n\t"                /* Store read bit as the bit 1 */
262 264
 
263 265
       /* bit 0 */
264 266
       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
265
-      " ldr %[work],[%[miso_port]]" "\n\t"              /* PDSR */
267
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
266 268
       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
267
-      " lsrs %[work],%[work],%[miso_shift]" "\n\t"      /* Isolate input into carry */
268
-      " adc %[bin],%[bin],%[bin]" "\n\t"                /* Shift left result and add the carry */
269
+      " bfi %[bin],%[work],#0,#1" "\n\t"                /* Store read bit as the bit 0 */
269 270
 
270
-      : [miso_port]"+r"( MISO_PORT_PLUS3C ),
271
-        [sck_mask]"+r"( SCK_MASK ),
272
-        [sck_port]"+r"( SCK_PORT_PLUS30 ),
273
-        [bin]"+r"(bin),
271
+      : [bin]"+r"(bin),
274 272
         [work]"+r"(work)
275
-      : [miso_shift]"M"( PIN_SHIFT(MISO_PIN) + 1 )      /* So we move to the carry */
273
+      : [bitband_miso_port]"r"( BITBAND_MISO_PORT ),
274
+        [sck_mask]"r"( SCK_MASK ),
275
+        [sck_port]"r"( SCK_PORT_PLUS30 )
276 276
       : "cc"
277 277
     );
278 278
 
279
-    return (uint8_t)bin;
279
+    return bin;
280 280
   }
281 281
 
282 282
   // run at ~4Mhz
@@ -317,10 +317,182 @@
317 317
     return b;
318 318
   }
319 319
 
320
-  // Pointers to generic functions
320
+  // Pointers to generic functions for byte transfers
321 321
   static pfnSpiTransfer spiTransferTx = spiTransferX;
322 322
   static pfnSpiTransfer spiTransferRx = spiTransferX;
323 323
 
324
+  // Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
325
+  static void spiTxBlock0(const uint8_t* ptr, uint32_t todo) {
326
+    register uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30;  /* SODR of port */
327
+    register uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
328
+    register uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30;    /* SODR of port */
329
+    register uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
330
+    register uint32_t work;
331
+    register uint32_t txval;
332
+
333
+    /* The software SPI routine */
334
+    __asm__ __volatile__(
335
+      ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax
336
+
337
+      " loop%=:" "\n\t"
338
+      " ldrb.w %[txval], [%[ptr]], #1" "\n\t"                   /* Load value to send, increment buffer */
339
+      " mvn %[txval],%[txval]" "\n\t"                           /* Negate value */
340
+
341
+      /* Bit 7 */
342
+      " ubfx %[work],%[txval],#7,#1" "\n\t"                     /* Place bit 7 in bit 0 of work*/
343
+
344
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
345
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
346
+      " ubfx %[work],%[txval],#6,#1" "\n\t"                     /* Place bit 6 in bit 0 of work*/
347
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
348
+
349
+      /* Bit 6 */
350
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
351
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
352
+      " ubfx %[work],%[txval],#5,#1" "\n\t"                     /* Place bit 5 in bit 0 of work*/
353
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
354
+
355
+      /* Bit 5 */
356
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
357
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
358
+      " ubfx %[work],%[txval],#4,#1" "\n\t"                     /* Place bit 4 in bit 0 of work*/
359
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
360
+
361
+      /* Bit 4 */
362
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
363
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
364
+      " ubfx %[work],%[txval],#3,#1" "\n\t"                     /* Place bit 3 in bit 0 of work*/
365
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
366
+
367
+      /* Bit 3 */
368
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
369
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
370
+      " ubfx %[work],%[txval],#2,#1" "\n\t"                     /* Place bit 2 in bit 0 of work*/
371
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
372
+
373
+      /* Bit 2 */
374
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
375
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
376
+      " ubfx %[work],%[txval],#1,#1" "\n\t"                     /* Place bit 1 in bit 0 of work*/
377
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
378
+
379
+      /* Bit 1 */
380
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */
381
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
382
+      " ubfx %[work],%[txval],#0,#1" "\n\t"                     /* Place bit 0 in bit 0 of work*/
383
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
384
+
385
+      /* Bit 0 */
386
+      " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */
387
+      " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */
388
+      " subs %[todo],#1" "\n\t"                                 /* Decrement count of pending words to send, update status */
389
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */
390
+      " bne.n loop%=" "\n\t"                                    /* Repeat until done */
391
+
392
+      : [ptr]"+r" ( ptr ) ,
393
+        [todo]"+r" ( todo ) ,
394
+        [work]"+r"( work ) ,
395
+        [txval]"+r"( txval )
396
+      : [mosi_mask]"r"( MOSI_MASK ),
397
+        [mosi_port]"r"( MOSI_PORT_PLUS30 ),
398
+        [sck_mask]"r"( SCK_MASK ),
399
+        [sck_port]"r"( SCK_PORT_PLUS30 )
400
+      : "cc"
401
+    );
402
+  }
403
+
404
+  static void spiRxBlock0(uint8_t* ptr, uint32_t todo) {
405
+    register uint32_t bin;
406
+    register uint32_t work;
407
+    register uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN));  /* PDSR of port in bitband area */
408
+    register uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30;    /* SODR of port */
409
+    register uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
410
+
411
+    /* The software SPI routine */
412
+    __asm__ __volatile__(
413
+      ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax
414
+
415
+      " loop%=:" "\n\t"
416
+
417
+      /* bit 7 */
418
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
419
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
420
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
421
+      " bfi %[bin],%[work],#7,#1" "\n\t"                /* Store read bit as the bit 7 */
422
+
423
+      /* bit 6 */
424
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
425
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
426
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
427
+      " bfi %[bin],%[work],#6,#1" "\n\t"                /* Store read bit as the bit 6 */
428
+
429
+      /* bit 5 */
430
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
431
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
432
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
433
+      " bfi %[bin],%[work],#5,#1" "\n\t"                /* Store read bit as the bit 5 */
434
+
435
+      /* bit 4 */
436
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
437
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
438
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
439
+      " bfi %[bin],%[work],#4,#1" "\n\t"                /* Store read bit as the bit 4 */
440
+
441
+      /* bit 3 */
442
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
443
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
444
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
445
+      " bfi %[bin],%[work],#3,#1" "\n\t"                /* Store read bit as the bit 3 */
446
+
447
+      /* bit 2 */
448
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
449
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
450
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
451
+      " bfi %[bin],%[work],#2,#1" "\n\t"                /* Store read bit as the bit 2 */
452
+
453
+      /* bit 1 */
454
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
455
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
456
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
457
+      " bfi %[bin],%[work],#1,#1" "\n\t"                /* Store read bit as the bit 1 */
458
+
459
+      /* bit 0 */
460
+      " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */
461
+      " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */
462
+      " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */
463
+      " bfi %[bin],%[work],#0,#1" "\n\t"                /* Store read bit as the bit 0 */
464
+
465
+      " subs %[todo],#1" "\n\t"                         /* Decrement count of pending words to send, update status */
466
+      " strb.w %[bin], [%[ptr]], #1" "\n\t"             /* Store read value into buffer, increment buffer pointer */
467
+      " bne.n loop%=" "\n\t"                            /* Repeat until done */
468
+
469
+      : [ptr]"+r"(ptr),
470
+        [todo]"+r"(todo),
471
+        [bin]"+r"(bin),
472
+        [work]"+r"(work)
473
+      : [bitband_miso_port]"r"( BITBAND_MISO_PORT ),
474
+        [sck_mask]"r"( SCK_MASK ),
475
+        [sck_port]"r"( SCK_PORT_PLUS30 )
476
+      : "cc"
477
+    );
478
+  }
479
+
480
+  static void spiTxBlockX(const uint8_t* buf, uint32_t todo) {
481
+    do {
482
+      (void) spiTransferTx(*buf++);
483
+    } while (--todo);
484
+  }
485
+
486
+  static void spiRxBlockX(uint8_t* buf, uint32_t todo) {
487
+    do {
488
+      *buf++ = spiTransferRx(0xff);
489
+    } while (--todo);
490
+  }
491
+
492
+  // Pointers to generic functions for block tranfers
493
+  static pfnSpiTxBlock spiTxBlock = spiTxBlockX;
494
+  static pfnSpiRxBlock spiRxBlock = spiRxBlockX;
495
+
324 496
   void spiBegin() {
325 497
     SET_OUTPUT(SS_PIN);
326 498
     WRITE(SS_PIN, HIGH);
@@ -329,6 +501,38 @@
329 501
     SET_OUTPUT(MOSI_PIN);
330 502
   }
331 503
 
504
+  uint8_t spiRec() {
505
+    WRITE(SS_PIN, LOW);
506
+    WRITE(MOSI_PIN, 1); /* Output 1s 1*/
507
+    uint8_t b = spiTransferRx(0xFF);
508
+    WRITE(SS_PIN, HIGH);
509
+    return b;
510
+  }
511
+
512
+  void spiRead(uint8_t* buf, uint16_t nbyte) {
513
+    uint32_t todo = nbyte;
514
+    if (todo == 0) return;
515
+
516
+    WRITE(SS_PIN, LOW);
517
+    WRITE(MOSI_PIN, 1); /* Output 1s 1*/
518
+    spiRxBlock(buf,nbyte);
519
+    WRITE(SS_PIN, HIGH);
520
+  }
521
+
522
+  void spiSend(uint8_t b) {
523
+    WRITE(SS_PIN, LOW);
524
+    (void) spiTransferTx(b);
525
+    WRITE(SS_PIN, HIGH);
526
+  }
527
+
528
+  void spiSendBlock(uint8_t token, const uint8_t* buf) {
529
+
530
+    WRITE(SS_PIN, LOW);
531
+    (void) spiTransferTx(token);
532
+    spiTxBlock(buf,512);
533
+    WRITE(SS_PIN, HIGH);
534
+  }
535
+
332 536
   /**
333 537
    * spiRate should be
334 538
    *  0 :  8 - 10 MHz
@@ -344,15 +548,21 @@
344 548
       case 0:
345 549
         spiTransferTx = spiTransferTx0;
346 550
         spiTransferRx = spiTransferRx0;
551
+        spiTxBlock = spiTxBlock0;
552
+        spiRxBlock = spiRxBlock0;
347 553
         break;
348 554
       case 1:
349 555
         spiTransferTx = spiTransfer1;
350 556
         spiTransferRx = spiTransfer1;
557
+        spiTxBlock = spiTxBlockX;
558
+        spiRxBlock = spiRxBlockX;
351 559
         break;
352 560
       default:
353 561
         spiDelayCyclesX4 = (F_CPU/1000000) >> (6 - spiRate);
354 562
         spiTransferTx = spiTransferX;
355 563
         spiTransferRx = spiTransferX;
564
+        spiTxBlock = spiTxBlockX;
565
+        spiRxBlock = spiRxBlockX;
356 566
         break;
357 567
     }
358 568
 
@@ -361,41 +571,6 @@
361 571
     WRITE(SCK_PIN, LOW);
362 572
   }
363 573
 
364
-  uint8_t spiRec() {
365
-    WRITE(SS_PIN, LOW);
366
-    WRITE(MOSI_PIN, 1); /* Output 1s 1*/
367
-    uint8_t b = spiTransferRx(0xFF);
368
-    WRITE(SS_PIN, HIGH);
369
-    return b;
370
-  }
371
-
372
-  void spiRead(uint8_t* buf, uint16_t nbyte) {
373
-    if (nbyte == 0) return;
374
-    WRITE(SS_PIN, LOW);
375
-    WRITE(MOSI_PIN, 1); /* Output 1s 1*/
376
-    for (int i = 0; i < nbyte; i++) {
377
-      buf[i] = spiTransferRx(0xff);
378
-    }
379
-    WRITE(SS_PIN, HIGH);
380
-  }
381
-
382
-  void spiSend(uint8_t b) {
383
-    WRITE(SS_PIN, LOW);
384
-    (void) spiTransferTx(b);
385
-    WRITE(SS_PIN, HIGH);
386
-  }
387
-
388
-  void spiSendBlock(uint8_t token, const uint8_t* buf) {
389
-
390
-    WRITE(SS_PIN, LOW);
391
-    (void) spiTransferTx(token);
392
-
393
-    for (uint16_t i = 0; i < 512; i++) {
394
-      (void) spiTransferTx(buf[i]);
395
-    }
396
-    WRITE(SS_PIN, HIGH);
397
-  }
398
-
399 574
   #pragma GCC reset_options
400 575
 
401 576
 #else

+ 30
- 25
Marlin/src/HAL/HAL_DUE/usb/conf_usb.h Zobrazit soubor

@@ -47,8 +47,12 @@
47 47
 #ifndef _CONF_USB_H_
48 48
 #define _CONF_USB_H_
49 49
 
50
+#undef UNUSED                           /* To avoid a macro clash as macros.h already defines it */
51
+#include "../../../core/macros.h"       /* For ENABLED()/DISABLED() */
52
+#include "../../../../Configuration.h"  /* For CUSTOM_MACHINE_NAME definition - We just need the name, no C++ allowed! */
50 53
 #include "compiler.h"
51 54
 
55
+
52 56
 /**
53 57
  * USB Device Configuration
54 58
  * @{
@@ -61,15 +65,15 @@
61 65
 #define  USB_DEVICE_MINOR_VERSION         0
62 66
 #define  USB_DEVICE_POWER                 100 // Consumption on Vbus line (mA)
63 67
 #define  USB_DEVICE_ATTR                  \
64
-	(USB_CONFIG_ATTR_SELF_POWERED)
68
+  (USB_CONFIG_ATTR_SELF_POWERED)
65 69
 // (USB_CONFIG_ATTR_BUS_POWERED)
66
-//	(USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
67
-//	(USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
70
+//  (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
71
+//  (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
68 72
 
69 73
 //! USB Device string definitions (Optional)
70
-#define  USB_DEVICE_MANUFACTURE_NAME      "MARLIN 3D"
71
-#define  USB_DEVICE_PRODUCT_NAME          "CDC and MSC"
72
-#define  USB_DEVICE_SERIAL_NAME           "123985739853" // Disk SN for MSC
74
+#define  USB_DEVICE_MANUFACTURE_NAME      "marlinfw.org"
75
+#define  USB_DEVICE_PRODUCT_NAME          CUSTOM_MACHINE_NAME
76
+#define  USB_DEVICE_SERIAL_NAME           "123985739853"
73 77
 
74 78
 /**
75 79
  * Device speeds support
@@ -94,10 +98,11 @@
94 98
  * @{
95 99
  */
96 100
 #define  UDC_VBUS_EVENT(b_vbus_high)
97
-#define  UDC_SOF_EVENT()                  
98
-#define  UDC_SUSPEND_EVENT()              
99
-#define  UDC_RESUME_EVENT()               
100
-#define  UDC_GET_EXTRA_STRING()           usb_task_extra_string()
101
+#define  UDC_SOF_EVENT()
102
+#define  UDC_SUSPEND_EVENT()
103
+#define  UDC_RESUME_EVENT()
104
+#define  UDC_GET_EXTRA_STRING()         usb_task_extra_string()
105
+#define  USB_DEVICE_SPECIFIC_REQUEST()  usb_task_other_requests()
101 106
 //@}
102 107
 
103 108
 /**
@@ -246,30 +251,30 @@
246 251
  */
247 252
 //! USB Interfaces descriptor structure
248 253
 #define UDI_COMPOSITE_DESC_T \
249
-	usb_iad_desc_t       udi_cdc_iad; \
250
-	udi_cdc_comm_desc_t  udi_cdc_comm; \
251
-	udi_cdc_data_desc_t  udi_cdc_data; \
252
-	udi_msc_desc_t       udi_msc
254
+  usb_iad_desc_t       udi_cdc_iad; \
255
+  udi_cdc_comm_desc_t  udi_cdc_comm; \
256
+  udi_cdc_data_desc_t  udi_cdc_data; \
257
+  udi_msc_desc_t       udi_msc
253 258
 
254 259
 //! USB Interfaces descriptor value for Full Speed
255 260
 #define UDI_COMPOSITE_DESC_FS \
256
-	.udi_cdc_iad   = UDI_CDC_IAD_DESC_0, \
257
-	.udi_cdc_comm  = UDI_CDC_COMM_DESC_0, \
258
-	.udi_cdc_data  = UDI_CDC_DATA_DESC_0_FS, \
259
-	.udi_msc       = UDI_MSC_DESC_FS
261
+  .udi_cdc_iad   = UDI_CDC_IAD_DESC_0, \
262
+  .udi_cdc_comm  = UDI_CDC_COMM_DESC_0, \
263
+  .udi_cdc_data  = UDI_CDC_DATA_DESC_0_FS, \
264
+  .udi_msc       = UDI_MSC_DESC_FS
260 265
 
261 266
 //! USB Interfaces descriptor value for High Speed
262 267
 #define UDI_COMPOSITE_DESC_HS \
263
-	.udi_cdc_iad   = UDI_CDC_IAD_DESC_0, \
264
-	.udi_cdc_comm  = UDI_CDC_COMM_DESC_0, \
265
-	.udi_cdc_data  = UDI_CDC_DATA_DESC_0_HS, \
266
-	.udi_msc       = UDI_MSC_DESC_HS
268
+  .udi_cdc_iad   = UDI_CDC_IAD_DESC_0, \
269
+  .udi_cdc_comm  = UDI_CDC_COMM_DESC_0, \
270
+  .udi_cdc_data  = UDI_CDC_DATA_DESC_0_HS, \
271
+  .udi_msc       = UDI_MSC_DESC_HS
267 272
 
268 273
 //! USB Interface APIs
269 274
 #define UDI_COMPOSITE_API \
270
-	&udi_api_cdc_comm, \
271
-	&udi_api_cdc_data, \
272
-	&udi_api_msc
275
+  &udi_api_cdc_comm, \
276
+  &udi_api_cdc_data, \
277
+  &udi_api_msc
273 278
 //@}
274 279
 
275 280
 

+ 220
- 115
Marlin/src/HAL/HAL_DUE/usb/usb_task.c Zobrazit soubor

@@ -40,9 +40,8 @@
40 40
  * \asf_license_stop
41 41
  *
42 42
  */
43
-/*
44
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45
- */
43
+
44
+// Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
46 45
 
47 46
 #ifdef ARDUINO_ARCH_SAM
48 47
 
@@ -52,135 +51,241 @@
52 51
 static volatile bool main_b_msc_enable = false;
53 52
 static volatile bool main_b_cdc_enable = false;
54 53
 
55
-void HAL_init(void) {
56
-	udd_disable();
57
-	UDD_SetStack(&USBD_ISR);
54
+void HAL_idletask(void) {
55
+  // Attend SD card access from the USB MSD -- Prioritize access to improve speed
56
+  int delay = 2;
57
+  while (main_b_msc_enable && --delay > 0) {
58
+    if (udi_msc_process_trans()) delay = 10000;
58 59
 
59
-	// Start USB stack to authorize VBus monitoring
60
-	udc_start();
60
+    // Reset the watchdog, just to be sure
61
+    REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5);
62
+  }
61 63
 }
62 64
 
63
-void HAL_idletask(void)
64
-{
65
-
66
-	// Attend SD card access from the USB MSD -- Priotize access to improve speed
67
-	int delay = 2;
68
-	while (main_b_msc_enable && --delay > 0 ) {
69
-		if (udi_msc_process_trans()) {
70
-			delay = 10000;
71
-		}
72
-		
73
-		/* Reset the watchdog, just to be sure */
74
-		REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5);
75
-	}
76
-}
65
+bool usb_task_msc_enable(void)                { return ((main_b_msc_enable = true)); }
66
+void usb_task_msc_disable(void)               { main_b_msc_enable = false; }
67
+bool usb_task_msc_isenabled(void)             { return main_b_msc_enable; }
68
+
69
+bool usb_task_cdc_enable(const uint8_t port)  { return ((main_b_cdc_enable = true)); }
70
+void usb_task_cdc_disable(const uint8_t port) { main_b_cdc_enable = false; }
71
+bool usb_task_cdc_isenabled(void)             { return main_b_cdc_enable; }
72
+
73
+/*! \brief Called by CDC interface
74
+ * Callback running when CDC device have received data
75
+ */
76
+void usb_task_cdc_rx_notify(const uint8_t port) { }
77 77
 
78
-/*! \brief Example of extra USB string management
79
- * This feature is available for single or composite device
80
- * which want implement additional USB string than
81
- * Manufacture, Product and serial number ID.
78
+/*! \brief Configures communication line
82 79
  *
83
- * return true, if the string ID requested is know and managed by this functions
80
+ * \param cfg      line configuration
84 81
  */
85
-bool usb_task_extra_string(void)
86
-{
87
-	static uint8_t udi_cdc_name[] = "CDC interface";
88
-	static uint8_t udi_msc_name[] = "MSC interface";
89
-
90
-	struct extra_strings_desc_t{
91
-		usb_str_desc_t header;
92
-		le16_t string[Max(sizeof(udi_cdc_name)-1, sizeof(udi_msc_name)-1)];
93
-	};
94
-	static UDC_DESC_STORAGE struct extra_strings_desc_t extra_strings_desc = {
95
-		.header.bDescriptorType = USB_DT_STRING
96
-	};
97
-
98
-	uint8_t i;
99
-	uint8_t *str;
100
-	uint8_t str_lgt=0;
101
-
102
-	// Link payload pointer to the string corresponding at request
103
-	switch (udd_g_ctrlreq.req.wValue & 0xff) {
104
-	case UDI_CDC_IAD_STRING_ID:
105
-		str_lgt = sizeof(udi_cdc_name)-1;
106
-		str = udi_cdc_name;
107
-		break;
108
-	case UDI_MSC_STRING_ID:
109
-		str_lgt = sizeof(udi_msc_name)-1;
110
-		str = udi_msc_name;
111
-		break;
112
-	default:
113
-		return false;
114
-	}
115
-
116
-	if (str_lgt!=0) {
117
-		for( i=0; i<str_lgt; i++) {
118
-			extra_strings_desc.string[i] = cpu_to_le16((le16_t)str[i]);
119
-		}
120
-		extra_strings_desc.header.bLength = 2+ (str_lgt)*2;
121
-		udd_g_ctrlreq.payload_size = extra_strings_desc.header.bLength;
122
-		udd_g_ctrlreq.payload = (uint8_t *) &extra_strings_desc;
123
-	}
124
-
125
-	// if the string is larger than request length, then cut it
126
-	if (udd_g_ctrlreq.payload_size > udd_g_ctrlreq.req.wLength) {
127
-		udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength;
128
-	}
129
-	return true;
130
-}
82
+void usb_task_cdc_config(const uint8_t port, usb_cdc_line_coding_t *cfg) { }
131 83
 
132
-bool usb_task_msc_enable(void)
133
-{
134
-	main_b_msc_enable = true;
135
-	return true;
84
+void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) {
85
+  if (b_enable) {
86
+  } else {
87
+  }
136 88
 }
137 89
 
138
-void usb_task_msc_disable(void)
139
-{
140
-	main_b_msc_enable = false;
141
-}
90
+/// Microsoft WCID descriptor
91
+typedef struct USB_MicrosoftCompatibleDescriptor_Interface {
92
+  uint8_t bFirstInterfaceNumber;
93
+  uint8_t reserved1;
94
+  uint8_t compatibleID[8];
95
+  uint8_t subCompatibleID[8];
96
+  uint8_t reserved2[6];
97
+} __attribute__((packed)) USB_MicrosoftCompatibleDescriptor_Interface;
142 98
 
143
-bool usb_task_msc_isenabled(void)
144
-{
145
-	return main_b_msc_enable;
146
-}
99
+typedef struct USB_MicrosoftCompatibleDescriptor {
100
+  uint32_t dwLength;
101
+  uint16_t bcdVersion;
102
+  uint16_t wIndex;
103
+  uint8_t bCount;
104
+  uint8_t reserved[7];
105
+  USB_MicrosoftCompatibleDescriptor_Interface interfaces[];
106
+} __attribute__((packed)) USB_MicrosoftCompatibleDescriptor;
147 107
 
148
-bool usb_task_cdc_enable(uint8_t port)
149
-{
150
-	main_b_cdc_enable = true;
151
-	return true;
152
-}
108
+// 3D Printer compatible descriptor
109
+static USB_MicrosoftCompatibleDescriptor microsoft_compatible_id_descriptor = {
110
+  .dwLength = sizeof(USB_MicrosoftCompatibleDescriptor) +
111
+              1*sizeof(USB_MicrosoftCompatibleDescriptor_Interface),
112
+  .bcdVersion = 0x0100,
113
+  .wIndex = 0x0004,
114
+  .bCount = 1,
115
+  .reserved = {0, 0, 0, 0, 0, 0, 0},
116
+  .interfaces = {
117
+    {
118
+      .bFirstInterfaceNumber = 0,
119
+      .reserved1 = 1,
120
+      .compatibleID = "3DPRINT",
121
+      .subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0},
122
+      .reserved2 = {0, 0, 0, 0, 0, 0},
123
+    }
124
+  }
125
+};
153 126
 
154
-void usb_task_cdc_disable(uint8_t port)
155
-{
156
-	main_b_cdc_enable = false;
157
-}
127
+#define xstr(s) str(s)
128
+#define str(s) #s
158 129
 
159
-bool usb_task_cdc_isenabled(void)
160
-{
161
-	return main_b_cdc_enable;
162
-}
130
+#define MS3DPRINT_CONFIG      u"MS3DPrintConfig"
131
+#define MS3DPRINT_CONFIG_DATA \
132
+  u"Base=SD\0"\
133
+  u"Job3DOutputAreaWidth=" xstr(X_BED_SIZE) "000\0"\
134
+  u"Job3DOutputAreaDepth=" xstr(Y_BED_SIZE) "000\0"\
135
+  u"Job3DOutputAreaHeight=" xstr(Z_MAX_POS) "000\0"\
136
+  u"filamentdiameter=1750\0"
163 137
 
164
-/*! \brief Called by CDC interface
165
- * Callback running when CDC device have received data
166
- */
167
-void usb_task_cdc_rx_notify(uint8_t port)
168
-{
138
+typedef struct USB_MicrosoftExtendedPropertiesDescriptor {
139
+  uint32_t  dwLength;
140
+  uint16_t  bcdVersion;
141
+  uint16_t  wIndex;
142
+  uint16_t  bCount;
143
+  uint32_t  dwPropertySize;
144
+  uint32_t  dwPropertyDataType;
145
+  uint16_t  wPropertyNameLength;
146
+  uint16_t  PropertyName[sizeof(MS3DPRINT_CONFIG)/sizeof(uint16_t)];
147
+  uint32_t  dwPropertyDataLength;
148
+  uint16_t  PropertyData[sizeof(MS3DPRINT_CONFIG_DATA)/sizeof(uint16_t)];
149
+} __attribute__((packed)) USB_MicrosoftExtendedPropertiesDescriptor;
150
+
151
+static USB_MicrosoftExtendedPropertiesDescriptor microsoft_extended_properties_descriptor = {
152
+  .dwLength = sizeof(USB_MicrosoftExtendedPropertiesDescriptor),
153
+  .bcdVersion = 0x0100,
154
+  .wIndex = 0x0005,
155
+  .bCount = 1,
156
+
157
+  .dwPropertySize = 4 + 4 + 2 + 4 + sizeof(MS3DPRINT_CONFIG) + sizeof(MS3DPRINT_CONFIG_DATA),
158
+  .dwPropertyDataType = 7, // (1=REG_SZ, 4=REG_DWORD, 7=REG_MULTI_SZ)
159
+  .wPropertyNameLength = sizeof(MS3DPRINT_CONFIG),
160
+  .PropertyName = MS3DPRINT_CONFIG,
161
+  .dwPropertyDataLength = sizeof(MS3DPRINT_CONFIG_DATA),
162
+  .PropertyData = MS3DPRINT_CONFIG_DATA
163
+};
164
+
165
+/**************************************************************************************************
166
+** WCID configuration information
167
+** Hooked into UDC via UDC_GET_EXTRA_STRING #define.
168
+*/
169
+bool usb_task_extra_string(void) {
170
+  static uint8_t udi_msft_magic[] = "MSFT100\xEE";
171
+  static uint8_t udi_cdc_name[] = "CDC interface";
172
+  static uint8_t udi_msc_name[] = "MSC interface";
173
+
174
+  struct extra_strings_desc_t {
175
+    usb_str_desc_t header;
176
+    le16_t string[Max(Max(sizeof(udi_cdc_name) - 1, sizeof(udi_msc_name) - 1), sizeof(udi_msft_magic) - 1)];
177
+  };
178
+  static UDC_DESC_STORAGE struct extra_strings_desc_t extra_strings_desc = {
179
+    .header.bDescriptorType = USB_DT_STRING
180
+  };
181
+
182
+  uint8_t *str;
183
+  uint8_t str_lgt = 0;
184
+
185
+  // Link payload pointer to the string corresponding at request
186
+  switch (udd_g_ctrlreq.req.wValue & 0xff) {
187
+  case UDI_CDC_IAD_STRING_ID:
188
+    str_lgt = sizeof(udi_cdc_name) - 1;
189
+    str = udi_cdc_name;
190
+    break;
191
+  case UDI_MSC_STRING_ID:
192
+    str_lgt = sizeof(udi_msc_name) - 1;
193
+    str = udi_msc_name;
194
+    break;
195
+  case 0xEE:
196
+    str_lgt = sizeof(udi_msft_magic) - 1;
197
+    str = udi_msft_magic;
198
+    break;
199
+  default:
200
+    return false;
201
+  }
202
+
203
+  for (uint8_t i = 0; i < str_lgt; i++)
204
+    extra_strings_desc.string[i] = cpu_to_le16((le16_t)str[i]);
205
+
206
+  extra_strings_desc.header.bLength = 2 + str_lgt * 2;
207
+  udd_g_ctrlreq.payload_size = extra_strings_desc.header.bLength;
208
+  udd_g_ctrlreq.payload = (uint8_t*)&extra_strings_desc;
209
+
210
+  // if the string is larger than request length, then cut it
211
+  if (udd_g_ctrlreq.payload_size > udd_g_ctrlreq.req.wLength) {
212
+    udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength;
213
+  }
214
+
215
+  return true;
169 216
 }
170 217
 
171
-/*! \brief Configures communication line
172
- *
173
- * \param cfg      line configuration
174
- */
175
-void usb_task_cdc_config(uint8_t port, usb_cdc_line_coding_t * cfg)
176
-{
218
+/**************************************************************************************************
219
+** Handle device requests that the ASF stack doesn't
220
+*/
221
+bool usb_task_other_requests(void) {
222
+  uint8_t* ptr = 0;
223
+  uint16_t size = 0;
224
+
225
+  if (Udd_setup_type() == USB_REQ_TYPE_VENDOR) {
226
+    //if (udd_g_ctrlreq.req.bRequest == 0x30)
227
+    if (1) {
228
+      if (udd_g_ctrlreq.req.wIndex == 0x04) {
229
+        ptr = (uint8_t*)&microsoft_compatible_id_descriptor;
230
+        size = (udd_g_ctrlreq.req.wLength);
231
+        if (size > microsoft_compatible_id_descriptor.dwLength)
232
+          size = microsoft_compatible_id_descriptor.dwLength;
233
+      }
234
+      else if (udd_g_ctrlreq.req.wIndex == 0x05) {
235
+        ptr = (uint8_t*)&microsoft_extended_properties_descriptor;
236
+        size = (udd_g_ctrlreq.req.wLength);
237
+        if (size > microsoft_extended_properties_descriptor.dwLength)
238
+          size = microsoft_extended_properties_descriptor.dwLength;
239
+      }
240
+      else
241
+        return false;
242
+    }
243
+  }
244
+
245
+  udd_g_ctrlreq.payload_size = size;
246
+  if (size == 0) {
247
+    udd_g_ctrlreq.callback = 0;
248
+    udd_g_ctrlreq.over_under_run = 0;
249
+  }
250
+  else
251
+    udd_g_ctrlreq.payload = ptr;
252
+
253
+  return true;
177 254
 }
178 255
 
179
-void usb_task_cdc_set_dtr(uint8_t port, bool b_enable)
180
-{
181
-	if (b_enable) {
182
-	} else {
183
-	}
256
+void HAL_init(void) {
257
+  uint16_t *ptr;
258
+
259
+  udd_disable();
260
+  UDD_SetStack(&USBD_ISR);
261
+
262
+  // Start USB stack to authorize VBus monitoring
263
+  udc_start();
264
+
265
+  // Patch in filament diameter - Be careful: String is in UNICODE (2bytes per char)
266
+  ptr = &microsoft_extended_properties_descriptor.PropertyData[0];
267
+  while (ptr[0] || ptr[1]) { // Double 0 flags end of resource
268
+
269
+    // Found the filamentdiameter= unicode string
270
+    if (ptr[0] == 'r' && ptr[1] == '=') {
271
+      char diam[16];
272
+      char *sptr;
273
+
274
+      // Patch in the filament diameter
275
+      sprintf_P(diam, PSTR("%d"), (int)((DEFAULT_NOMINAL_FILAMENT_DIA) * 1000.0));
276
+
277
+      // And copy it to the proper place, expanding it to unicode
278
+      sptr = &diam[0];
279
+      ptr += 2;
280
+      while (*sptr) *ptr++ = *sptr++;
281
+
282
+      // Done!
283
+      break;
284
+    }
285
+
286
+    // Go to the next character
287
+    ptr++;
288
+  }
184 289
 }
185 290
 
186
-#endif
291
+#endif // ARDUINO_ARCH_SAM

+ 9
- 5
Marlin/src/HAL/HAL_DUE/usb/usb_task.h Zobrazit soubor

@@ -66,33 +66,37 @@ void usb_task_msc_disable(void);
66 66
  *
67 67
  * \retval true if cdc startup is successfully done
68 68
  */
69
-bool usb_task_cdc_enable(uint8_t port);
69
+bool usb_task_cdc_enable(const uint8_t port);
70 70
 
71 71
 /*! \brief Closes the communication port
72 72
  * This is called by CDC interface when USB Host disable it.
73 73
  */
74
-void usb_task_cdc_disable(uint8_t port);
74
+void usb_task_cdc_disable(const uint8_t port);
75 75
 
76 76
 /*! \brief Save new DTR state to change led behavior.
77 77
  * The DTR notify that the terminal have open or close the communication port.
78 78
  */
79
-void usb_task_cdc_set_dtr(uint8_t port, bool b_enable);
79
+void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable);
80 80
 
81 81
 /*! \brief Called by UDC when USB Host request a extra string different
82 82
  * of this specified in USB device descriptor
83 83
  */
84 84
 bool usb_task_extra_string(void);
85 85
 
86
+/*! \brief Called by UDC when USB Host performs unknown requests
87
+ */
88
+bool usb_task_other_requests(void);
89
+
86 90
 /*! \brief Called by CDC interface
87 91
  * Callback running when CDC device have received data
88 92
  */
89
-void usb_task_cdc_rx_notify(uint8_t port);
93
+void usb_task_cdc_rx_notify(const uint8_t port);
90 94
 
91 95
 /*! \brief Configures communication line
92 96
  *
93 97
  * \param cfg      line configuration
94 98
  */
95
-void usb_task_cdc_config(uint8_t port, usb_cdc_line_coding_t * cfg); 
99
+void usb_task_cdc_config(const uint8_t port, usb_cdc_line_coding_t *cfg);
96 100
 
97 101
 /* The USB device interrupt
98 102
  */

Loading…
Zrušit
Uložit