Ver código fonte

Fixes for the Arduino DUE HAL (Serial Port, Graphics Display, EEPROM emulation) (#8651)

* Fixing the DUE serial port assignments: Now -1 means the SAM3x USB Device emulating a serial port, and 0 means the USB to serial adapter included as a programming port

* Improving the Fast IO port access implementation on Arduino DUE

* Implemented EEPROM emulation on Due by storing data on the internal FLASH (with wear leveling)

* Implemented a Software SPI for the ST7920 graphics display for the Arduino RAMPS for DUE, as the default one in u8glib is clocking data too fast on ARM, and the display does not understand it.

* Fixing the case where the serial port selected is the USB device

* Adding configuration for the Makerparts 3D printer (www.makerparts.net)

* Tuned MakerParts acceleration on X and Y axis so it never loses steps. Also adjusted pulses per mm to match default hw configuration

* Fine tuned Maximum acceleration for MakerParts printer

* Style cleanup

* Style cleanup (2)

* Style fixes (3)

* Fixing the DUE serial port assignments: Now -1 means the SAM3x USB Device emulating a serial port, and 0 means the USB to serial adapter included as a programming port

* Improving the Fast IO port access implementation on Arduino DUE

* Implemented EEPROM emulation on Due by storing data on the internal FLASH (with wear leveling)

* Implemented a Software SPI for the ST7920 graphics display for the Arduino RAMPS for DUE, as the default one in u8glib is clocking data too fast on ARM, and the display does not understand it.

* Fixing the case where the serial port selected is the USB device

* Adding configuration for the Makerparts 3D printer (www.makerparts.net)

* Tuned MakerParts acceleration on X and Y axis so it never loses steps. Also adjusted pulses per mm to match default hw configuration

* Fine tuned Maximum acceleration for MakerParts printer

* Style cleanup

* Style changes to u8g_dev_st7920_128_64_sw_spi.cpp

* Even more improvements to the FastIO HAL for DUE. Now WRITE() is 2 ASM instructions, if value is constant, and 5 cycles if value is not constant. Previously, it was 7..8 cycles

* After some problems and debugging, seems we need to align the interrupt vector table to 256 bytes, otherwise, the program sometimes stops working

* Moved comments out of macro, otherwise, token pasting does not properly work sometimes

* Improved Software SPI implementation on DUE: Now it honors the selected speed passed to spiInit(). This allows much faster SDCARD access, improving SDCARD menus and reducing latency

* Update u8g_dev_st7920_128_64_sw_spi.cpp

* Disabling EEPROM over FLASH emulatiion if an I2C or SPI EEPROM is present
Eduardo José Tagle 7 anos atrás
pai
commit
ac168a03c8

+ 1034
- 0
Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 1
- 7
Marlin/src/HAL/HAL_DUE/HAL_Due.h Ver arquivo

43
 
43
 
44
 #if SERIAL_PORT == -1
44
 #if SERIAL_PORT == -1
45
   #define MYSERIAL SerialUSB
45
   #define MYSERIAL SerialUSB
46
-#elif SERIAL_PORT == 0
47
-  #define MYSERIAL customizedSerial
48
-#elif SERIAL_PORT == 1
49
-  #define MYSERIAL customizedSerial
50
-#elif SERIAL_PORT == 2
51
-  #define MYSERIAL customizedSerial
52
-#elif SERIAL_PORT == 3
46
+#elif SERIAL_PORT >= 0 && SERIAL_PORT <= 4
53
   #define MYSERIAL customizedSerial
47
   #define MYSERIAL customizedSerial
54
 #endif
48
 #endif
55
 
49
 

+ 134
- 16
Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp Ver arquivo

52
   // --------------------------------------------------------------------------
52
   // --------------------------------------------------------------------------
53
   // software SPI
53
   // software SPI
54
   // --------------------------------------------------------------------------
54
   // --------------------------------------------------------------------------
55
-  // bitbanging transfer
56
-  // run at ~100KHz (necessary for init)
57
-  static uint8_t spiTransfer(uint8_t b) { // using Mode 0
58
-    for (int bits = 0; bits < 8; bits++) {
59
-      if (b & 0x80) {
60
-        WRITE(MOSI_PIN, HIGH);
55
+
56
+  /* ---------------- Delay Cycles routine -------------- */
57
+
58
+  /* https://blueprints.launchpad.net/gcc-arm-embedded/+spec/delay-cycles */
59
+
60
+  #define nop() __asm__ __volatile__("nop;\n\t":::)
61
+
62
+  FORCE_INLINE static void __delay_4cycles(uint32_t cy) { // +1 cycle
63
+    #if ARCH_PIPELINE_RELOAD_CYCLES<2
64
+      #define EXTRA_NOP_CYCLES "nop"
65
+    #else
66
+      #define EXTRA_NOP_CYCLES ""
67
+    #endif
68
+
69
+    __asm__ __volatile__(
70
+      ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax
71
+
72
+      "loop%=:" "\n\t"
73
+      " subs %[cnt],#1" "\n\t"
74
+      EXTRA_NOP_CYCLES "\n\t"
75
+      " bne loop%=" "\n\t"
76
+      : [cnt]"+r"(cy) // output: +r means input+output
77
+      : // input:
78
+      : "cc" // clobbers:
79
+    );
80
+  }
81
+
82
+  FORCE_INLINE static void DELAY_CYCLES(uint32_t x) {
83
+
84
+    if (__builtin_constant_p(x)) {
85
+
86
+      #define MAXNOPS 4
87
+
88
+      if (x <= (MAXNOPS)) {
89
+        switch(x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
61
       }
90
       }
62
-      else {
63
-        WRITE(MOSI_PIN, LOW);
91
+      else { // because of +1 cycle inside delay_4cycles
92
+        const uint32_t rem = (x - 1) % (MAXNOPS);
93
+        switch(rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
94
+        if ((x = (x - 1) / (MAXNOPS)))
95
+          __delay_4cycles(x); // if need more then 4 nop loop is more optimal
64
       }
96
       }
65
-      b <<= 1;
97
+    }
98
+    else
99
+      __delay_4cycles(x / 4);
100
+  }
101
+
102
+  /* ---------------- Delay in nanoseconds and in microseconds */
103
+
104
+  #define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000) / 1000)
105
+
106
+  typedef uint8_t (*pfnSpiTransfer) (uint8_t b);
107
+
108
+  // bitbanging transfer
109
+  #define SWSPI_BIT_XFER(n) \
110
+      WRITE(MOSI_PIN, bout & (1 << n)); \
111
+      WRITE(SCK_PIN, HIGH); /* Sampling point */\
112
+      /* (implicit by overhead) DELAY_NS(63); 5.3 cycles @ 84mhz */ \
113
+      bin |= (READ(MISO_PIN) != 0) << n; \
114
+      WRITE(SCK_PIN, LOW); /* Toggling point*/ \
115
+      /* (implicit by overhead) DELAY_NS(63); 5.3 cycles @ 84mhz */
116
+
117
+  // run at ~8 .. ~10Mhz
118
+  static uint8_t spiTransfer0(uint8_t bout) { // using Mode 0
119
+    volatile uint8_t bin = 0; /* volatile to disable deferred processing */
120
+    SWSPI_BIT_XFER(7);
121
+    SWSPI_BIT_XFER(6);
122
+    SWSPI_BIT_XFER(5);
123
+    SWSPI_BIT_XFER(4);
124
+    SWSPI_BIT_XFER(3);
125
+    SWSPI_BIT_XFER(2);
126
+    SWSPI_BIT_XFER(1);
127
+    SWSPI_BIT_XFER(0);
128
+    return bin;
129
+  }
130
+
131
+  // run at ~4Mhz
132
+  static uint8_t spiTransfer1(uint8_t b) { // using Mode 0
133
+    int bits = 8;
134
+    do {
135
+      WRITE(MOSI_PIN, b & 0x80);
136
+      b <<= 1; // little setup time
66
 
137
 
67
       WRITE(SCK_PIN, HIGH);
138
       WRITE(SCK_PIN, HIGH);
68
-      delayMicroseconds(5U);
139
+      DELAY_NS(125); // 10 cycles @ 84mhz
140
+
141
+      b |= (READ(MISO_PIN) != 0);
69
 
142
 
70
-      if (READ(MISO_PIN)) {
71
-        b |= 1;
72
-      }
73
       WRITE(SCK_PIN, LOW);
143
       WRITE(SCK_PIN, LOW);
74
-      delayMicroseconds(5U);
75
-    }
144
+      DELAY_NS(125); // 10 cycles @ 84mhz
145
+    } while (--bits);
76
     return b;
146
     return b;
77
   }
147
   }
78
 
148
 
149
+  // all the others
150
+  static uint32_t spiDelayCyclesX4 = (F_CPU/1000000); // 4uS => 125khz
151
+
152
+  static uint8_t spiTransferX(uint8_t b) { // using Mode 0
153
+    int bits = 8;
154
+    do {
155
+      WRITE(MOSI_PIN, b & 0x80);
156
+      b <<= 1; // little setup time
157
+
158
+      WRITE(SCK_PIN, HIGH);
159
+      __delay_4cycles(spiDelayCyclesX4);
160
+
161
+      b |= (READ(MISO_PIN) != 0);
162
+
163
+      WRITE(SCK_PIN, LOW);
164
+      __delay_4cycles(spiDelayCyclesX4);
165
+    } while (--bits);
166
+    return b;
167
+  }
168
+
169
+  // Use the generic one
170
+  static pfnSpiTransfer spiTransfer = spiTransferX;
171
+
79
   void spiBegin() {
172
   void spiBegin() {
80
     SET_OUTPUT(SS_PIN);
173
     SET_OUTPUT(SS_PIN);
81
     WRITE(SS_PIN, HIGH);
174
     WRITE(SS_PIN, HIGH);
84
     SET_OUTPUT(MOSI_PIN);
177
     SET_OUTPUT(MOSI_PIN);
85
   }
178
   }
86
 
179
 
180
+  /**
181
+   * spiRate should be
182
+   *  0 :  8 - 10 MHz
183
+   *  1 :  4 - 5 MHz
184
+   *  2 :  2 - 2.5 MHz
185
+   *  3 :  1 - 1.25 MHz
186
+   *  4 :  500 - 625 kHz
187
+   *  5 :  250 - 312 kHz
188
+   *  6 :  125 - 156 kHz
189
+   */
87
   void spiInit(uint8_t spiRate) {
190
   void spiInit(uint8_t spiRate) {
88
-    UNUSED(spiRate);
191
+    switch (spiRate) {
192
+      case 0:
193
+        spiTransfer = spiTransfer0;
194
+        break;
195
+      case 1:
196
+        spiTransfer = spiTransfer1;
197
+        break;
198
+      default:
199
+        spiDelayCyclesX4 = (F_CPU/1000000) >> (6 - spiRate);
200
+        spiTransfer = spiTransferX;
201
+        break;
202
+    }
203
+
89
     WRITE(SS_PIN, HIGH);
204
     WRITE(SS_PIN, HIGH);
90
     WRITE(MOSI_PIN, HIGH);
205
     WRITE(MOSI_PIN, HIGH);
91
     WRITE(SCK_PIN, LOW);
206
     WRITE(SCK_PIN, LOW);
137
     UNUSED(response);
252
     UNUSED(response);
138
     WRITE(SS_PIN, HIGH);
253
     WRITE(SS_PIN, HIGH);
139
   }
254
   }
255
+
256
+  #pragma GCC reset_options
257
+
140
 #else
258
 #else
141
   // --------------------------------------------------------------------------
259
   // --------------------------------------------------------------------------
142
   // hardware SPI
260
   // hardware SPI

+ 5
- 3
Marlin/src/HAL/HAL_DUE/InterruptVectors_Due.cpp Ver arquivo

35
 #include "HAL_Due.h"
35
 #include "HAL_Due.h"
36
 #include "InterruptVectors_Due.h"
36
 #include "InterruptVectors_Due.h"
37
 
37
 
38
-/* The relocated Exception/Interrupt Table - Must be aligned to 128bytes,
39
-   as bits 0-6 on VTOR register are reserved and must be set to 0 */
40
-__attribute__ ((aligned(128)))
38
+/* The relocated Exception/Interrupt Table - According to the ARM
39
+   reference manual, alignment to 128 bytes should suffice, but in
40
+   practice, we need alignment to 256 bytes to make this work in all
41
+   cases */
42
+__attribute__ ((aligned(256)))
41
 static DeviceVectors ram_tab = { NULL };
43
 static DeviceVectors ram_tab = { NULL };
42
 
44
 
43
 /**
45
 /**

+ 549
- 545
Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 17
- 6
Marlin/src/HAL/HAL_DUE/fastio_Due.h Ver arquivo

30
  * Description: Fast IO functions for Arduino Due and compatible (SAM3X8E)
30
  * Description: Fast IO functions for Arduino Due and compatible (SAM3X8E)
31
  *
31
  *
32
  * For ARDUINO_ARCH_SAM
32
  * For ARDUINO_ARCH_SAM
33
+ * Note the code here was specifically crafted by disassembling what GCC produces
34
+ * out of it, so GCC is able to optimize it out as much as possible to the least
35
+ * amount of instructions. Be very carefull if you modify them, as "clean code"
36
+ * leads to less efficient compiled code!!
33
  */
37
  */
34
 
38
 
35
 #ifndef _FASTIO_DUE_H
39
 #ifndef _FASTIO_DUE_H
55
 #define _READ(IO) ((bool)(DIO ## IO ## _WPORT -> PIO_PDSR & (MASK(DIO ## IO ## _PIN))))
59
 #define _READ(IO) ((bool)(DIO ## IO ## _WPORT -> PIO_PDSR & (MASK(DIO ## IO ## _PIN))))
56
 
60
 
57
 /// Write to a pin
61
 /// Write to a pin
58
-#define _WRITE_VAR(IO, v) do {  if (v) {g_APinDescription[IO].pPort->PIO_SODR = g_APinDescription[IO].ulPin; } \
59
-                                    else {g_APinDescription[IO].pPort->PIO_CODR = g_APinDescription[IO].ulPin; } \
60
-                                 } while (0)
62
+#define _WRITE_VAR(IO, v)  do { \
63
+  volatile Pio* port = g_APinDescription[IO].pPort; \
64
+  uint32_t mask = g_APinDescription[IO].ulPin; \
65
+  if (v) port->PIO_SODR = mask; \
66
+  else port->PIO_CODR = mask; \
67
+} while(0)
61
 
68
 
62
-#define _WRITE(IO, v) do {  if (v) {DIO ## IO ## _WPORT -> PIO_SODR = MASK(DIO ## IO ##_PIN); } \
63
-                                else {DIO ##  IO ## _WPORT -> PIO_CODR = MASK(DIO ## IO ## _PIN); }; \
64
-                             } while (0)
69
+/// Write to a pin
70
+#define _WRITE(IO, v) do { \
71
+  volatile Pio* port = (DIO ##  IO ## _WPORT); \
72
+  uint32_t mask = MASK(DIO ## IO ## _PIN); \
73
+  if (v) port->PIO_SODR = mask; \
74
+  else port->PIO_CODR = mask; \
75
+} while(0)
65
 
76
 
66
 /// toggle a pin
77
 /// toggle a pin
67
 #define _TOGGLE(IO)  _WRITE(IO, !READ(IO))
78
 #define _TOGGLE(IO)  _WRITE(IO, !READ(IO))

+ 5
- 0
Marlin/src/HAL/HAL_DUE/persistent_store_impl.cpp Ver arquivo

6
 
6
 
7
 #if ENABLED(EEPROM_SETTINGS)
7
 #if ENABLED(EEPROM_SETTINGS)
8
 
8
 
9
+extern void eeprom_flush(void);
10
+
9
 namespace HAL {
11
 namespace HAL {
10
 namespace PersistentStore {
12
 namespace PersistentStore {
11
 
13
 
14
 }
16
 }
15
 
17
 
16
 bool access_finish(){
18
 bool access_finish(){
19
+#if DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
20
+  eeprom_flush();
21
+#endif
17
   return true;
22
   return true;
18
 }
23
 }
19
 
24
 

+ 2
- 1
Marlin/src/HAL/HAL_DUE/spi_pins.h Ver arquivo

53
   #define MOSI_PIN          51
53
   #define MOSI_PIN          51
54
 #endif
54
 #endif
55
 
55
 
56
-#define SS_PIN            SDSS // A.28, A.29, B.21, C.26, C.29
56
+/* A.28, A.29, B.21, C.26, C.29 */
57
+#define SS_PIN            SDSS
57
 
58
 
58
 #endif /* SPI_PINS_H_ */
59
 #endif /* SPI_PINS_H_ */

+ 1789
- 0
Marlin/src/config/examples/MakerParts/Configuration.h
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 1525
- 0
Marlin/src/config/examples/MakerParts/Configuration_adv.h
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 83
- 0
Marlin/src/config/examples/MakerParts/_Bootscreen.h Ver arquivo

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
+ * Custom Bitmap for splashscreen
25
+ *
26
+ * You may use one of the following tools to generate the C++ bitmap array from
27
+ * a black and white image:
28
+ *
29
+ *  - http://www.marlinfw.org/tools/u8glib/converter.html
30
+ *  - http://www.digole.com/tools/PicturetoC_Hex_converter.php
31
+ */
32
+#include <avr/pgmspace.h>
33
+
34
+#define CUSTOM_BOOTSCREEN_TIMEOUT   2500
35
+#define CUSTOM_BOOTSCREEN_BMPWIDTH  128
36
+#define CUSTOM_BOOTSCREEN_BMPHEIGHT 44
37
+
38
+const unsigned char custom_start_bmp[] PROGMEM = {
39
+0x00,0x1f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
40
+,0x00,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
41
+,0x07,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
42
+,0x1f,0xff,0xff,0xff,0xc0,0x0f,0x80,0x7c,0x07,0xe0,0x3f,0x0f,0xdf,0xff,0x7f,0xf0
43
+,0x3f,0xff,0xff,0xff,0xe0,0x0f,0xc0,0xfc,0x07,0xe0,0x3f,0x1f,0x9f,0xff,0x7f,0xfc
44
+,0x7f,0xbf,0xff,0xef,0xf0,0x0f,0xc0,0xfc,0x0f,0xf0,0x3f,0x1f,0x1f,0xff,0x7f,0xfe
45
+,0x7e,0x0f,0xff,0x83,0xf0,0x0f,0xe1,0xfc,0x0f,0xf0,0x3f,0x3e,0x1f,0xff,0x7f,0xfe
46
+,0x7c,0x07,0xff,0x01,0xf0,0x0f,0xe1,0xfc,0x1f,0xf8,0x3f,0x7e,0x1f,0x80,0x7c,0x3e
47
+,0x7c,0x03,0xfe,0x01,0xf0,0x0f,0xf3,0xfc,0x1f,0xf8,0x3f,0xfc,0x1f,0x80,0x7c,0x1e
48
+,0x7c,0x01,0xfc,0x01,0xf0,0x0f,0xf3,0xfc,0x1f,0xf8,0x3f,0xf8,0x1f,0xfc,0x7c,0x3e
49
+,0x7c,0x00,0xf8,0x01,0xf0,0x0f,0xff,0xfc,0x3e,0x7c,0x3f,0xf8,0x1f,0xfc,0x7f,0xfe
50
+,0x7c,0x00,0x70,0x01,0xf0,0x0f,0xff,0xfc,0x3e,0x7c,0x3f,0xfc,0x1f,0xfc,0x7f,0xfe
51
+,0x7c,0x00,0x20,0x01,0xf0,0x0f,0xff,0xfc,0x3e,0x7c,0x3f,0xfc,0x1f,0xfc,0x7f,0xfc
52
+,0x7c,0x00,0x00,0x01,0xf0,0x0f,0xbf,0x7c,0x7f,0xfe,0x3f,0xfe,0x1f,0xfc,0x7f,0xf8
53
+,0x7c,0x00,0x00,0x01,0xf0,0x0f,0xbf,0x7c,0x7f,0xfe,0x3f,0xfe,0x1f,0x80,0x7f,0xf8
54
+,0x7c,0x00,0x00,0x01,0xf0,0x0f,0x9e,0x7c,0x7f,0xfe,0x3f,0x3f,0x1f,0x80,0x7c,0xf8
55
+,0x7c,0x06,0x03,0x01,0xf0,0x0f,0x9e,0x7c,0xff,0xff,0x3f,0x3f,0x1f,0xff,0x7c,0xfc
56
+,0x7c,0x07,0x07,0x01,0xf0,0x0f,0x8c,0x7c,0xff,0xff,0x3f,0x1f,0x9f,0xff,0x7c,0xfc
57
+,0x7c,0x07,0x8f,0x01,0xf0,0x0f,0x80,0x7c,0xf8,0x1f,0x3f,0x1f,0x9f,0xff,0x7c,0x7e
58
+,0x7c,0x07,0xdf,0x01,0xf0,0x0f,0x80,0x7d,0xf8,0x1f,0xbf,0x0f,0xdf,0xff,0x7c,0x3f
59
+,0x7c,0x07,0xff,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
60
+,0x7c,0x07,0xff,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
61
+,0x7c,0x07,0xff,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
62
+,0x7c,0x07,0xff,0x01,0xf0,0x0f,0xfe,0x03,0xf0,0x1f,0xf8,0x3f,0xff,0x87,0xf8,0x00
63
+,0x7c,0x07,0xff,0x01,0xf0,0x0f,0xff,0x03,0xf0,0x1f,0xfe,0x3f,0xff,0x9f,0xfe,0x00
64
+,0x7c,0x07,0xff,0x01,0xe0,0x0f,0xff,0x87,0xf8,0x1f,0xff,0x3f,0xff,0x9f,0xfe,0x00
65
+,0x3c,0x0f,0xff,0x81,0xe0,0x0f,0xff,0xc7,0xf8,0x1f,0xff,0xbf,0xff,0xbf,0xfe,0x00
66
+,0x3c,0x0f,0xff,0x81,0xe0,0x0f,0xff,0xc7,0xf8,0x1f,0xff,0xbf,0xff,0xbf,0x3c,0x00
67
+,0x1e,0x0f,0xff,0x83,0xc0,0x0f,0x87,0xcf,0xfc,0x1f,0x0f,0xc1,0xf0,0x3e,0x00,0x00
68
+,0x1e,0x0f,0xff,0x83,0xc0,0x0f,0x83,0xcf,0xfc,0x1f,0x07,0xc1,0xf0,0x3f,0xc0,0x00
69
+,0x0f,0x0f,0xff,0x87,0x80,0x0f,0x87,0xcf,0x3c,0x1f,0x0f,0x81,0xf0,0x3f,0xf8,0x00
70
+,0x0f,0x0f,0xff,0x87,0x80,0x0f,0xff,0xdf,0x3e,0x1f,0xff,0x81,0xf0,0x1f,0xfe,0x00
71
+,0x07,0x8f,0xff,0x8f,0x00,0x0f,0xff,0x9f,0x3e,0x1f,0xff,0x81,0xf0,0x1f,0xfe,0x00
72
+,0x07,0xcf,0xff,0x9f,0x00,0x0f,0xff,0x1f,0x3e,0x1f,0xff,0x01,0xf0,0x07,0xff,0x00
73
+,0x03,0xef,0xff,0xbe,0x00,0x0f,0xfc,0x3f,0xff,0x1f,0xfe,0x01,0xf0,0x00,0x7f,0x00
74
+,0x01,0xef,0xff,0xbc,0x00,0x0f,0x80,0x3f,0xff,0x1f,0x3e,0x01,0xf0,0x18,0x1f,0x00
75
+,0x00,0xef,0xff,0xb8,0x00,0x0f,0x80,0x3f,0xff,0x1f,0x3f,0x01,0xf0,0x1e,0x3f,0x7c
76
+,0x00,0x6f,0xff,0xb0,0x00,0x0f,0x80,0x7f,0xff,0x9f,0x3f,0x01,0xf0,0x3f,0xff,0x7c
77
+,0x00,0x2f,0xff,0xa0,0x00,0x0f,0x80,0x7f,0xff,0x9f,0x1f,0x81,0xf0,0x7f,0xfe,0x7c
78
+,0x00,0x0f,0xff,0x80,0x00,0x0f,0x80,0x7c,0x0f,0x9f,0x1f,0x81,0xf0,0x3f,0xfe,0x7c
79
+,0x00,0x0f,0xff,0x80,0x00,0x0f,0x80,0xfc,0x0f,0xdf,0x0f,0xc1,0xf0,0x0f,0xf8,0x7c
80
+,0x00,0x07,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
81
+,0x00,0x03,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
82
+,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
83
+};

+ 2
- 1
Marlin/src/core/macros.h Ver arquivo

35
 #define _YMAX_ 201
35
 #define _YMAX_ 201
36
 #define _ZMAX_ 301
36
 #define _ZMAX_ 301
37
 
37
 
38
-#define FORCE_INLINE __attribute__((always_inline)) inline
38
+#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
39
+#define  FORCE_INLINE  __attribute__((always_inline)) inline
39
 #define _UNUSED      __attribute__((unused))
40
 #define _UNUSED      __attribute__((unused))
40
 #define _O0          __attribute__((optimize("O0")))
41
 #define _O0          __attribute__((optimize("O0")))
41
 #define _Os          __attribute__((optimize("Os")))
42
 #define _Os          __attribute__((optimize("Os")))

+ 7
- 0
Marlin/src/lcd/dogm/HAL_LCD_class_defines.h Ver arquivo

62
 };
62
 };
63
 
63
 
64
 
64
 
65
+extern u8g_dev_t u8g_dev_st7920_128x64_custom_sw_spi;
66
+class U8GLIB_ST7920_128X64_CUSTOM_SW_SPI : public U8GLIB {
67
+  public:
68
+    U8GLIB_ST7920_128X64_CUSTOM_SW_SPI() 
69
+    : U8GLIB(&u8g_dev_st7920_128x64_custom_sw_spi) 
70
+    {  }
71
+};
65
 
72
 
66
 extern u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire;
73
 extern u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire;
67
 class U8GLIB_SH1106_128X64_2X_I2C_2_WIRE : public U8GLIB {
74
 class U8GLIB_SH1106_128X64_2X_I2C_2_WIRE : public U8GLIB {

+ 276
- 0
Marlin/src/lcd/dogm/u8g_dev_st7920_128_64_sw_spi.cpp Ver arquivo

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
+ * PLEASE NOTE >>>
25
+ *  We need our custom implementation for Software SPI, as the default implementation
26
+ * of U8GLIB, when running in an ARM based board, is too fast and the display will not
27
+ * recognize commands and/or data at such speeds. This implementation autoderives the
28
+ * required delays to get the maximum possible performance by using the F_CPU macro that
29
+ * specifies the CPU speed. According to the ST7920 datasheet, the maximum SCLK is 1MHz.
30
+ */
31
+
32
+#ifndef ULCDST7920_SWSPI_H
33
+#define ULCDST7920_SWSPI_H
34
+
35
+#include "../../inc/MarlinConfig.h"
36
+
37
+#if ENABLED(U8GLIB_ST7920)
38
+
39
+#include <U8glib.h>
40
+#include "HAL_LCD_com_defines.h"
41
+
42
+#define ST7920_CLK_PIN  LCD_PINS_D4
43
+#define ST7920_DAT_PIN  LCD_PINS_ENABLE
44
+#define ST7920_CS_PIN   LCD_PINS_RS
45
+
46
+//#define PAGE_HEIGHT 8   //128 byte framebuffer
47
+#define PAGE_HEIGHT 16    //256 byte framebuffer
48
+//#define PAGE_HEIGHT 32  //512 byte framebuffer
49
+
50
+#define LCD_PIXEL_WIDTH 128
51
+#define LCD_PIXEL_HEIGHT 64
52
+
53
+//set optimization so ARDUINO optimizes this file
54
+#pragma GCC optimize (3)
55
+
56
+/* ---------------- Delay Cycles routine -------------- */
57
+
58
+#ifdef __arm__
59
+/* https://blueprints.launchpad.net/gcc-arm-embedded/+spec/delay-cycles */
60
+
61
+#define nop() __asm__ __volatile__("nop;\n\t":::)
62
+
63
+FORCE_INLINE static void __delay_4cycles(uint32_t cy) { // +1 cycle
64
+  #if ARCH_PIPELINE_RELOAD_CYCLES<2
65
+    #define EXTRA_NOP_CYCLES "nop"
66
+  #else
67
+    #define EXTRA_NOP_CYCLES ""
68
+  #endif
69
+
70
+  __asm__ __volatile__(
71
+    ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax
72
+
73
+    "loop%=:" "\n\t"
74
+    " subs %[cnt],#1" "\n\t"
75
+    EXTRA_NOP_CYCLES "\n\t"
76
+    " bne loop%=" "\n\t"
77
+    : [cnt]"+r"(cy) // output: +r means input+output
78
+    : // input:
79
+    : "cc" // clobbers:
80
+  );
81
+}
82
+
83
+FORCE_INLINE static void DELAY_CYCLES(uint32_t x) {
84
+
85
+  if (__builtin_constant_p(x)) {
86
+
87
+    #define MAXNOPS 4
88
+
89
+    if (x <= (MAXNOPS)) {
90
+      switch(x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
91
+    }
92
+    else { // because of +1 cycle inside delay_4cycles
93
+      const uint32_t rem = (x - 1) % (MAXNOPS);
94
+      switch(rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
95
+      if ((x = (x - 1) / (MAXNOPS)))
96
+        __delay_4cycles(x); // if need more then 4 nop loop is more optimal
97
+    }
98
+  }
99
+  else
100
+    __delay_4cycles(x / 4);
101
+  }
102
+
103
+#ifdef __TEST_DELAY
104
+
105
+  void calibrateTimer() {
106
+
107
+    // Use DWT to calibrate cycles
108
+    uint32_t count = 0;
109
+
110
+    // addresses of registers
111
+    volatile uint32_t *DWT_CONTROL = (uint32_t *)0xE0001000,
112
+                      *DWT_CYCCNT = (uint32_t *)0xE0001004,
113
+                      *DEMCR = (uint32_t *)0xE000EDFC;
114
+
115
+    cli();
116
+
117
+    // enable the use DWT
118
+    *DEMCR = *DEMCR | 0x01000000;
119
+
120
+    // Reset cycle counter
121
+    *DWT_CYCCNT = 0;
122
+
123
+    // enable cycle counter
124
+    *DWT_CONTROL = *DWT_CONTROL | 1;
125
+
126
+    // Perform a delay of 10000 cycles
127
+    DELAY_CYCLES(10000U);
128
+
129
+    // number of cycles stored in count variable
130
+    count = *DWT_CYCCNT;
131
+
132
+    sei();
133
+
134
+    SERIAL_ECHO_START();
135
+    SERIAL_ECHOLNPAIR("calibrated Cycles: ", (int)count);
136
+  }
137
+
138
+#endif // __TEST_DELAY
139
+
140
+#elif defined(__AVR__)
141
+  #define DELAY_CYCLES(cycles) __builtin_avr_delay_cycles(cycles)
142
+#else
143
+  #error "DELAY_CYCLES not implemented for this architecture."
144
+#endif
145
+
146
+/* ---------------- Delay in nanoseconds and in microseconds */
147
+
148
+#define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000) / 1000)
149
+#define DELAY_US(x) DELAY_CYCLES( (x) * (F_CPU/1000000))
150
+
151
+/* ---------------- ST7920 commands ------------------------ */
152
+
153
+#ifdef __arm__
154
+
155
+  /* ARM: Plain implementation is more than enough */
156
+  static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
157
+    uint8_t n = 8;
158
+    do {
159
+      WRITE(ST7920_CLK_PIN, LOW);
160
+      WRITE(ST7920_DAT_PIN, val & 0x80);
161
+      DELAY_NS(500);
162
+      WRITE(ST7920_CLK_PIN, HIGH);
163
+      DELAY_NS(500);
164
+      val <<= 1;
165
+    } while (--n);
166
+  }
167
+
168
+#else // !ARM
169
+
170
+  /* AVR: Unrolling loop makes sense */
171
+  #define ST7920_SND_BIT(nr)              \
172
+    WRITE(ST7920_CLK_PIN, LOW);           \
173
+    WRITE(ST7920_DAT_PIN, TEST(val, nr)); \
174
+    DELAY_NS(500);                        \
175
+    WRITE(ST7920_CLK_PIN, HIGH);          \
176
+    DELAY_NS(500);
177
+
178
+  static void ST7920_SWSPI_SND_8BIT(const uint8_t val) {
179
+    ST7920_SND_BIT(7); // MSBit
180
+    ST7920_SND_BIT(6); //
181
+    ST7920_SND_BIT(5); //
182
+    ST7920_SND_BIT(4); //
183
+    ST7920_SND_BIT(3); //
184
+    ST7920_SND_BIT(2); //
185
+    ST7920_SND_BIT(1); //
186
+    ST7920_SND_BIT(0); // LSBit
187
+  }
188
+
189
+#endif // !ARM
190
+
191
+#define ST7920_CS()              { WRITE(ST7920_CS_PIN,1); DELAY_NS(200); }
192
+#define ST7920_NCS()             { WRITE(ST7920_CS_PIN,0); }
193
+#define ST7920_SET_CMD()         { ST7920_SWSPI_SND_8BIT(0xF8); DELAY_US(3); }
194
+#define ST7920_SET_DAT()         { ST7920_SWSPI_SND_8BIT(0xFA); DELAY_US(3); }
195
+#define ST7920_WRITE_BYTE(a)     { ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xF0u)); ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4u)); DELAY_US(3); }
196
+#define ST7920_WRITE_BYTES(p,l)  { for (uint8_t i = l + 1; --i;) { ST7920_SWSPI_SND_8BIT(*p&0xF0); ST7920_SWSPI_SND_8BIT(*p<<4); p++; } DELAY_US(3); }
197
+
198
+
199
+uint8_t u8g_dev_st7920_custom_sw_spi_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
200
+
201
+  uint8_t i, y;
202
+  switch (msg) {
203
+    case U8G_DEV_MSG_INIT: {
204
+
205
+      /* Set to output and write */
206
+      OUT_WRITE(ST7920_CS_PIN, LOW);
207
+      OUT_WRITE(ST7920_DAT_PIN, LOW);
208
+      OUT_WRITE(ST7920_CLK_PIN, HIGH);
209
+
210
+      ST7920_CS();
211
+      u8g_Delay(120);                //initial delay for boot up
212
+
213
+      ST7920_SET_CMD();
214
+      ST7920_WRITE_BYTE(0x08);       //display off, cursor+blink off
215
+      ST7920_WRITE_BYTE(0x01);       //clear CGRAM ram
216
+      u8g_Delay(15);                 //delay for CGRAM clear
217
+      ST7920_WRITE_BYTE(0x3E);       //extended mode + GDRAM active
218
+      for (y = 0; y < (LCD_PIXEL_HEIGHT) / 2; y++) { //clear GDRAM
219
+        ST7920_WRITE_BYTE(0x80 | y); //set y
220
+        ST7920_WRITE_BYTE(0x80);     //set x = 0
221
+        ST7920_SET_DAT();
222
+        for (i = 0; i < 2 * (LCD_PIXEL_WIDTH) / 8; i++) //2x width clears both segments
223
+          ST7920_WRITE_BYTE(0);
224
+        ST7920_SET_CMD();
225
+      }
226
+
227
+      ST7920_WRITE_BYTE(0x0C);       //display on, cursor+blink off
228
+      ST7920_NCS();
229
+    }
230
+    break;
231
+
232
+    case U8G_DEV_MSG_STOP:
233
+      break;
234
+
235
+    case U8G_DEV_MSG_PAGE_NEXT: {
236
+      u8g_pb_t* pb = (u8g_pb_t*)(dev->dev_mem);
237
+      y = pb->p.page_y0;
238
+      uint8_t* ptr = (uint8_t*)pb->buf;
239
+
240
+      ST7920_CS();
241
+      for (i = 0; i < PAGE_HEIGHT; i ++) {
242
+        ST7920_SET_CMD();
243
+        if (y < 32) {
244
+          ST7920_WRITE_BYTE(0x80 | y);   //y
245
+          ST7920_WRITE_BYTE(0x80);       //x=0
246
+        }
247
+        else {
248
+          ST7920_WRITE_BYTE(0x80 | (y - 32)); //y
249
+          ST7920_WRITE_BYTE(0x80 | 8);   //x=64
250
+        }
251
+        ST7920_SET_DAT();
252
+        ST7920_WRITE_BYTES(ptr, (LCD_PIXEL_WIDTH) / 8); //ptr is incremented inside of macro
253
+        y++;
254
+      }
255
+
256
+      ST7920_NCS();
257
+    }
258
+    break;
259
+  }
260
+  #if PAGE_HEIGHT == 8
261
+    return u8g_dev_pb8h1_base_fn(u8g, dev, msg, arg);
262
+  #elif PAGE_HEIGHT == 16
263
+    return u8g_dev_pb16h1_base_fn(u8g, dev, msg, arg);
264
+  #else
265
+    return u8g_dev_pb32h1_base_fn(u8g, dev, msg, arg);
266
+  #endif
267
+}
268
+
269
+static uint8_t   u8g_dev_st7920_128x64_custom_sw_spi_buf[(LCD_PIXEL_WIDTH) * (PAGE_HEIGHT) / 8] U8G_NOCOMMON;
270
+static u8g_pb_t  u8g_dev_st7920_128x64_custom_sw_spi_pb = {{PAGE_HEIGHT, LCD_PIXEL_HEIGHT, 0, 0, 0}, LCD_PIXEL_WIDTH, u8g_dev_st7920_128x64_custom_sw_spi_buf};
271
+u8g_dev_t u8g_dev_st7920_128x64_custom_sw_spi = {u8g_dev_st7920_custom_sw_spi_128x64_fn, &u8g_dev_st7920_128x64_custom_sw_spi_pb, &u8g_com_null_fn};
272
+
273
+#pragma GCC reset_options
274
+
275
+#endif // U8GLIB_ST7920
276
+#endif // ULCDST7920_SWSPI_H

+ 5
- 0
Marlin/src/lcd/ultralcd_impl_DOGM.h Ver arquivo

169
   #else
169
   #else
170
     U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card)
170
     U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card)
171
   #endif
171
   #endif
172
+#elif ENABLED(U8GLIB_ST7920) && defined(__arm__)
173
+  // RepRap Discount Full Graphics Smart Controller on an ARM target
174
+    U8GLIB_ST7920_128X64_CUSTOM_SW_SPI u8g;
175
+    
172
 #elif ENABLED(U8GLIB_ST7920)
176
 #elif ENABLED(U8GLIB_ST7920)
173
   // RepRap Discount Full Graphics Smart Controller
177
   // RepRap Discount Full Graphics Smart Controller
174
     //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card, on AVR does not use standard LCD adapter)
178
     //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI (shared with SD card, on AVR does not use standard LCD adapter)
176
     U8GLIB_ST7920_128X64_RRD u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT
180
     U8GLIB_ST7920_128X64_RRD u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT
177
                                                                            // AVR version ignores these pin settings
181
                                                                            // AVR version ignores these pin settings
178
                                                                            // HAL version uses these pin settings
182
                                                                            // HAL version uses these pin settings
183
+    
179
 #elif ENABLED(CARTESIO_UI)
184
 #elif ENABLED(CARTESIO_UI)
180
   // The CartesioUI display
185
   // The CartesioUI display
181
     //U8GLIB_DOGM128_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes
186
     //U8GLIB_DOGM128_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes

Carregando…
Cancelar
Salvar