Browse Source

3 ms speedup for ST7920 and delay for BOARD_3DRAG

and saving ~1k memory
by limiting the `#pragma GCC optimize (3)` optimisation to `ultralcd_st7920_u8glib_rrd.h`. These optimisation was and is not done for all the other displays, is the reason for the big additionally use of memory, because the complete 'ultralcd.cpp' and 'dogm_lcd_implementation.h' was optimised (sadly i did not observe a change in speed).

Unrolling the loop in `ST7920_SWSPI_SND_8BIT()`, what i expected the optimiser to do, by hand, saved some speed by eliminating the loop variable (i) compares and increases. Every CPU cycle in this loop costs at least 0.5ms per display update because it's executed more than 1k times/s.

The delays are now pre-filled with the calculated values for 4.5V driven ST7920.
A way to simply add __your__ timing into the configuration was made.

At 4.5V
1.) The CLK signal needs to be at least 200ns high and 200ns low.
2.) The DAT pin needs to be set at least 40ns before CLK goes high and must stay at this value until 40ns after CLK went high.

A nop takes one processor cycle.
For 16MHz one nop lasts 62.5ns.
For 20MHz one not lasts 50ns.

To fulfill condition 1.) we need 200/62.5 = 3.2 => 4 cycles (200/50 = 4 => 4). For the low phase, setting the pin takes much longer. For the high phase we (theoretically) have to throw in 2 nops, because changing the CLK takes only 2 cycles.

Condition 2.) is always fulfilled because the processor needs two cycles (100 - 125ns) for switching the CLK pin.


Needs tests and feedback.
Especially i cant test 20MHz, 3DRAG and displays supplied wit less than 5V.
Are the delays right? Please experiment with longer or shorter delays. And give feedback.

Already tested are 5 displays with 4.9V - 5.1V at 16MHz where no delays are needed.
AnHardt 9 years ago
parent
commit
56c42b572c
1 changed files with 109 additions and 12 deletions
  1. 109
    12
      Marlin/ultralcd_st7920_u8glib_rrd.h

+ 109
- 12
Marlin/ultralcd_st7920_u8glib_rrd.h View File

@@ -27,9 +27,6 @@
27 27
 
28 28
 #if ENABLED(U8GLIB_ST7920)
29 29
 
30
-//set optimization so ARDUINO optimizes this file
31
-#pragma GCC optimize (3)
32
-
33 30
 #define ST7920_CLK_PIN  LCD_PINS_D4
34 31
 #define ST7920_DAT_PIN  LCD_PINS_ENABLE
35 32
 #define ST7920_CS_PIN   LCD_PINS_RS
@@ -43,20 +40,119 @@
43 40
 
44 41
 #include <U8glib.h>
45 42
 
43
+//set optimization so ARDUINO optimizes this file
44
+#pragma GCC push_options
45
+#pragma GCC optimize (3)
46
+
47
+#define DELAY_0_NOP  ;
48
+#define DELAY_1_NOP  __asm__("nop\n\t");
49
+#define DELAY_2_NOP  __asm__("nop\n\t" "nop\n\t");
50
+#define DELAY_3_NOP  __asm__("nop\n\t" "nop\n\t" "nop\n\t");
51
+#define DELAY_4_NOP  __asm__("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t");
52
+
53
+
54
+// If you want you can define your own set of delays in Configuration.h
55
+//#define ST7920_DELAY_1 DELAY_0_NOP
56
+//#define ST7920_DELAY_2 DELAY_0_NOP
57
+//#define ST7920_DELAY_3 DELAY_0_NOP
58
+
59
+#if F_CPU >= 20000000
60
+  #ifndef ST7920_DELAY_1
61
+    #define ST7920_DELAY_1 DELAY_0_NOP
62
+  #endif
63
+  #ifndef ST7920_DELAY_2
64
+    #define ST7920_DELAY_2 DELAY_0_NOP
65
+  #endif
66
+  #ifndef ST7920_DELAY_3
67
+    #define ST7920_DELAY_3 DELAY_2_NOP
68
+  #endif
69
+#elif MOTHERBOARD == BOARD_3DRAG
70
+  #ifndef ST7920_DELAY_1
71
+    #define ST7920_DELAY_1 DELAY_0_NOP
72
+  #endif
73
+  #ifndef ST7920_DELAY_2
74
+    #define ST7920_DELAY_2 DELAY_0_NOP
75
+  #endif
76
+  #ifndef ST7920_DELAY_3
77
+    #define ST7920_DELAY_3 DELAY_2_NOP
78
+  #endif
79
+#elif F_CPU == 16000000
80
+  #ifndef ST7920_DELAY_1
81
+    #define ST7920_DELAY_1 DELAY_0_NOP
82
+  #endif
83
+  #ifndef ST7920_DELAY_2
84
+    #define ST7920_DELAY_2 DELAY_0_NOP
85
+  #endif
86
+  #ifndef ST7920_DELAY_3
87
+    #define ST7920_DELAY_3 DELAY_2_NOP
88
+  #endif
89
+#else
90
+  #error "No valid condition for delays in 'ultralcd_st7920_u8glib_rrd.h'"
91
+#endif
92
+
46 93
 static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
47
-  uint8_t i;
48
-  for (i = 0; i < 8; i++) {
49 94
     WRITE(ST7920_CLK_PIN,0);
50
-    #if F_CPU == 20000000
51
-      __asm__("nop\n\t");
52
-    #endif
95
+    ST7920_DELAY_1
53 96
     WRITE(ST7920_DAT_PIN,val&0x80);
54 97
     val<<=1;
98
+    ST7920_DELAY_2
99
+    WRITE(ST7920_CLK_PIN,1);
100
+    ST7920_DELAY_3
101
+
102
+    WRITE(ST7920_CLK_PIN,0);
103
+    ST7920_DELAY_1
104
+    WRITE(ST7920_DAT_PIN,val&0x80);
105
+    val<<=1;
106
+    ST7920_DELAY_2
107
+    WRITE(ST7920_CLK_PIN,1);
108
+    ST7920_DELAY_3
109
+
110
+    WRITE(ST7920_CLK_PIN,0);
111
+    ST7920_DELAY_1
112
+    WRITE(ST7920_DAT_PIN,val&0x80);
113
+    val<<=1;
114
+    ST7920_DELAY_2
115
+    WRITE(ST7920_CLK_PIN,1);
116
+    ST7920_DELAY_3
117
+
118
+    WRITE(ST7920_CLK_PIN,0);
119
+    ST7920_DELAY_1
120
+    WRITE(ST7920_DAT_PIN,val&0x80);
121
+    val<<=1;
122
+    ST7920_DELAY_2
123
+    WRITE(ST7920_CLK_PIN,1);
124
+    ST7920_DELAY_3
125
+
126
+    WRITE(ST7920_CLK_PIN,0);
127
+    ST7920_DELAY_1
128
+    WRITE(ST7920_DAT_PIN,val&0x80);
129
+    val<<=1;
130
+    ST7920_DELAY_2
131
+    WRITE(ST7920_CLK_PIN,1);
132
+    ST7920_DELAY_3
133
+
134
+    WRITE(ST7920_CLK_PIN,0);
135
+    ST7920_DELAY_1
136
+    WRITE(ST7920_DAT_PIN,val&0x80);
137
+    val<<=1;
138
+    ST7920_DELAY_2
139
+    WRITE(ST7920_CLK_PIN,1);
140
+    ST7920_DELAY_3
141
+
142
+    WRITE(ST7920_CLK_PIN,0);
143
+    ST7920_DELAY_1
144
+    WRITE(ST7920_DAT_PIN,val&0x80);
145
+    val<<=1;
146
+    ST7920_DELAY_2
147
+    WRITE(ST7920_CLK_PIN,1);
148
+    ST7920_DELAY_3
149
+
150
+    WRITE(ST7920_CLK_PIN,0);
151
+    ST7920_DELAY_1
152
+    WRITE(ST7920_DAT_PIN,val&0x80);
153
+    val<<=1;
154
+    ST7920_DELAY_2
55 155
     WRITE(ST7920_CLK_PIN,1);
56
-    #if F_CPU == 20000000
57
-      __asm__("nop\n\t""nop\n\t");
58
-    #endif
59
-  }
60 156
 }
61 157
 
62 158
 #define ST7920_CS()              {WRITE(ST7920_CS_PIN,1);u8g_10MicroDelay();}
@@ -138,6 +234,7 @@ class U8GLIB_ST7920_128X64_RRD : public U8GLIB {
138 234
   U8GLIB_ST7920_128X64_RRD(uint8_t dummy) : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi) { UNUSED(dummy); }
139 235
 };
140 236
 
237
+#pragma GCC pop_options
141 238
 
142 239
 #endif //U8GLIB_ST7920
143 240
 #endif //ULCDST7920_H

Loading…
Cancel
Save