Subversion Repositories DashDisplay

Rev

Rev 2 | Rev 5 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 4
Line 1... Line 1...
1
/*********************************************************************
1
/*********************************************************************
2
This is a library for our Monochrome OLEDs based on SSD1306 drivers
2
 This is a library for our Monochrome OLEDs based on SSD1306 drivers
3
 
3
 
4
  Pick one up today in the adafruit shop!
4
 Pick one up today in the adafruit shop!
5
  ------> http://www.adafruit.com/category/63_98
5
 ------> http://www.adafruit.com/category/63_98
6
 
6
 
7
These displays use SPI to communicate, 4 or 5 pins are required to  
7
 These displays use SPI to communicate, 4 or 5 pins are required to
8
interface
8
 interface
9
 
9
 
10
Adafruit invests time and resources providing this open source code,
10
 Adafruit invests time and resources providing this open source code,
11
please support Adafruit and open-source hardware by purchasing
11
 please support Adafruit and open-source hardware by purchasing
12
products from Adafruit!
12
 products from Adafruit!
13
 
13
 
14
Written by Limor Fried/Ladyada  for Adafruit Industries.  
14
 Written by Limor Fried/Ladyada  for Adafruit Industries.
15
BSD license, check license.txt for more information
15
 BSD license, check license.txt for more information
16
All text above, and the splash screen below must be included in any redistribution
16
 All text above, and the splash screen below must be included in any redistribution
17
 
17
 
18
This code is taken from the ADAfruit library - it is used for playing with an OLED screen
18
 This code is taken from the ADAfruit library - it is used for playing with an OLED screen
19
 
19
 
20
*********************************************************************/
20
 *********************************************************************/
21
#include <stdint.h>
21
#include <stdint.h>
22
#include <string.h>
22
#include <string.h>
23
#include "stm32f1xx_hal.h"
23
#include "stm32f1xx_hal.h"
24
#include "SSD1306.h"
24
#include "SSD1306.h"
25
 
25
 
26
 
-
 
27
#define swap(x,y) { typeof(x)t = x; x=y; y=t; }
26
#define swap(x,y) { typeof(x)t = x; x=y; y=t; }
28
#define abs(x)      ((x)>0?(x):-(x))
27
#define abs(x)      ((x)>0?(x):-(x))
29
 
28
 
30
static uint8_t rotation = 0;
29
static uint8_t rotation = 0;
31
const uint16_t WIDTH  = SSD1306_LCDWIDTH;
30
const uint16_t WIDTH = SSD1306_LCDWIDTH;
32
const uint16_t HEIGHT = SSD1306_LCDHEIGHT;
31
const uint16_t HEIGHT = SSD1306_LCDHEIGHT;
33
 
32
 
34
extern SPI_HandleTypeDef hspi1;
33
extern SPI_HandleTypeDef hspi1;
35
 
34
 
36
 
-
 
37
 
-
 
38
 
-
 
39
// the memory buffer for the LCD
35
// the memory buffer for the LCD
40
 
36
 
41
// pointer to the current display - affects buffer used and also chipselect
37
// pointer to the current display - affects buffer used and also chipselect
42
static int cd = 0;
38
static int cd = 0;
43
 
39
 
44
uint8_t display_buffer[MAX_PHYS_DISPLAYS][SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8];
40
uint8_t display_buffer[MAX_PHYS_DISPLAYS][SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH
-
 
41
                / 8];
45
 
42
 
46
inline uint8_t * display_address(void)
43
inline uint8_t * display_address(void) {
47
{
-
 
48
        return (uint8_t *)(&display_buffer[cd]);
44
        return (uint8_t *) (&display_buffer[cd]);
49
}
45
}
50
 
46
 
51
inline uint8_t getRotation(void)
47
inline uint8_t getRotation(void) {
52
{
-
 
53
        return rotation;
48
        return rotation;
54
}
49
}
55
 
50
 
56
inline int16_t width(void)
51
inline int16_t width(void) {
57
{
-
 
58
        switch (rotation)
52
        switch (rotation) {
59
        {
-
 
60
        case 0:
53
        case 0:
61
                return WIDTH;
54
                return WIDTH;
62
                break;
55
                break;
63
        case 1:
56
        case 1:
64
                return WIDTH;
57
                return WIDTH;
Line 67... Line 60...
67
                return HEIGHT;
60
                return HEIGHT;
68
                break;
61
                break;
69
        case 3:
62
        case 3:
70
                return -WIDTH;
63
                return -WIDTH;
71
                break;
64
                break;
72
    }
65
        }
73
  return 0;
66
        return 0;
74
}
67
}
75
 
68
 
76
inline int16_t height(void)
69
inline int16_t height(void) {
77
{
-
 
78
        switch (rotation)
70
        switch (rotation) {
79
        {
-
 
80
        case 0:
71
        case 0:
81
                return HEIGHT;
72
                return HEIGHT;
82
                break;
73
                break;
83
        case 1:
74
        case 1:
84
                return HEIGHT;
75
                return HEIGHT;
Line 87... Line 78...
87
                return WIDTH;
78
                return WIDTH;
88
                break;
79
                break;
89
        case 3:
80
        case 3:
90
                return -HEIGHT;
81
                return -HEIGHT;
91
                break;
82
                break;
92
    }
83
        }
93
        return 0;
84
        return 0;
94
}
85
}
95
 
86
 
96
 
-
 
97
inline void fastSPIwrite(uint8_t d)
87
inline void fastSPIwrite(uint8_t d) {
98
{
-
 
99
  uint8_t buffer[1];
88
        uint8_t buffer[1];
100
  buffer[0] = d;
89
        buffer[0] = d;
101
// todo chipselect based on 'cd' buffer choice
90
// todo chipselect based on 'cd' buffer choice
102
 
91
 
103
  HAL_SPI_Transmit(&hspi1, buffer, 1, 2);
92
        HAL_SPI_Transmit(&hspi1, buffer, 1, 2);
104
 
93
 
105
}
94
}
106
 
95
 
107
 
-
 
108
// the most basic function, set a single pixel
96
// the most basic function, set a single pixel
109
inline void drawPixel(int16_t x, int16_t y, uint16_t color) {
97
inline void drawPixel(int16_t x, int16_t y, uint16_t color) {
110
  if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
98
        if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
111
    return;
99
                return;
112
 
100
 
113
  // check rotation, move pixel around if necessary
101
        // check rotation, move pixel around if necessary
114
  switch (getRotation()) {
102
        switch (getRotation()) {
115
  case 1:
103
        case 1:
116
    swap(x, y);
104
                swap(x, y)
-
 
105
                ;
117
    x = WIDTH - x - 1;
106
                x = WIDTH - x - 1;
118
    break;
107
                break;
119
  case 2:
108
        case 2:
120
    x = WIDTH - x - 1;
109
                x = WIDTH - x - 1;
121
    y = HEIGHT - y - 1;
110
                y = HEIGHT - y - 1;
122
    break;
111
                break;
123
  case 3:
112
        case 3:
124
    swap(x, y);
113
                swap(x, y)
125
    y = HEIGHT - y - 1;
-
 
126
    break;
-
 
127
  }  
-
 
128
 
-
 
129
  // x is which column
-
 
130
  switch(color)
-
 
131
  {
114
                ;
132
  case BLACK:
-
 
133
    display_buffer[cd][x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << (y&7));
-
 
134
    break;
-
 
135
 
-
 
136
  default:
-
 
137
  case  WHITE:
115
                y = HEIGHT - y - 1;
138
    display_buffer[cd][x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << (y&7));
-
 
139
    break;
-
 
140
 
-
 
141
  case  INVERT:
-
 
142
        display_buffer[cd][x+ (y/8)*SSD1306_LCDWIDTH] ^= (1 << (y&7));
-
 
143
        break;
116
                break;
144
  }
-
 
145
}
117
        }
146
 
118
 
-
 
119
        // x is which column
-
 
120
        switch (color) {
-
 
121
        case BLACK:
-
 
122
                display_buffer[cd][x + (y / 8) * SSD1306_LCDWIDTH] &= ~(1 << (y & 7));
-
 
123
                break;
-
 
124
 
-
 
125
        default:
-
 
126
        case WHITE:
-
 
127
                display_buffer[cd][x + (y / 8) * SSD1306_LCDWIDTH] |= (1 << (y & 7));
-
 
128
                break;
147
 
129
 
-
 
130
        case INVERT:
-
 
131
                display_buffer[cd][x + (y / 8) * SSD1306_LCDWIDTH] ^= (1 << (y & 7));
-
 
132
                break;
148
 
133
        }
-
 
134
}
149
 
135
 
150
void ssd1306_begin(uint8_t vccstate, uint8_t i2caddr) {
136
void ssd1306_begin(uint8_t vccstate, uint8_t i2caddr) {
151
 
137
 
-
 
138
        HAL_GPIO_WritePin(SPI_RESET_GPIO_Port, SPI_RESET_Pin, GPIO_PIN_SET);
152
 
139
 
-
 
140
        // VDD (3.3V) goes high at start, lets just chill for a ms
-
 
141
        HAL_Delay(1);
-
 
142
        // bring reset low
-
 
143
        HAL_GPIO_WritePin(SPI_RESET_GPIO_Port, SPI_RESET_Pin, GPIO_PIN_RESET);
-
 
144
        // wait 10ms
-
 
145
        HAL_Delay(10);
-
 
146
        // bring out of reset
153
   HAL_GPIO_WritePin(SPI_RESET_GPIO_Port,SPI_RESET_Pin,GPIO_PIN_SET);
147
        HAL_GPIO_WritePin(SPI_RESET_GPIO_Port, SPI_RESET_Pin, GPIO_PIN_SET);
-
 
148
        // turn on VCC (9V?)
-
 
149
 
-
 
150
        for (cd = 0; cd < 2; cd++) {
-
 
151
#if defined SSD1306_128_32
-
 
152
                // Init sequence for 128x32 OLED module
-
 
153
                ssd1306_command(SSD1306_DISPLAYOFF);// 0xAE
-
 
154
                ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);// 0xD5
-
 
155
                ssd1306_command(0x80);// the suggested ratio 0x80
-
 
156
                ssd1306_command(SSD1306_SETMULTIPLEX);// 0xA8
-
 
157
                ssd1306_command(0x1F);
-
 
158
                ssd1306_command(SSD1306_SETDISPLAYOFFSET);// 0xD3
-
 
159
                ssd1306_command(0x0);// no offset
-
 
160
                ssd1306_command(SSD1306_SETSTARTLINE | 0x0);// line #0
-
 
161
                ssd1306_command(SSD1306_CHARGEPUMP);// 0x8D
-
 
162
                if (vccstate == SSD1306_EXTERNALVCC)
-
 
163
                {       ssd1306_command(0x10);}
-
 
164
                else
-
 
165
                {       ssd1306_command(0x14);}
-
 
166
                ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
-
 
167
                ssd1306_command(0x00);// 0x0 act like ks0108
-
 
168
                ssd1306_command(SSD1306_SEGREMAP | 0x1);
-
 
169
                ssd1306_command(SSD1306_COMSCANDEC);
-
 
170
                ssd1306_command(SSD1306_SETCOMPINS);// 0xDA
-
 
171
                ssd1306_command(0x02);
-
 
172
                ssd1306_command(SSD1306_SETCONTRAST);// 0x81
-
 
173
                ssd1306_command(0x8F);
-
 
174
                ssd1306_command(SSD1306_SETPRECHARGE);// 0xd9
-
 
175
                if (vccstate == SSD1306_EXTERNALVCC)
-
 
176
                {       ssd1306_command(0x22);}
-
 
177
                else
-
 
178
                {       ssd1306_command(0xF1);}
-
 
179
                ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
-
 
180
                ssd1306_command(0x40);
-
 
181
                ssd1306_command(SSD1306_DISPLAYALLON_RESUME);// 0xA4
-
 
182
                ssd1306_command(SSD1306_NORMALDISPLAY);// 0xA6
-
 
183
#endif
-
 
184
 
-
 
185
#if defined SSD1306_128_64
-
 
186
                // Init sequence for 128x64 OLED module
-
 
187
                ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
-
 
188
                ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
-
 
189
                ssd1306_command(0x80);                       // the suggested ratio 0x80
-
 
190
                ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
-
 
191
                ssd1306_command(0x3F);
-
 
192
                ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
-
 
193
                ssd1306_command(0x0);                                   // no offset
-
 
194
                ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
-
 
195
                ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
-
 
196
                if (vccstate == SSD1306_EXTERNALVCC) {
-
 
197
                        ssd1306_command(0x10);
-
 
198
                } else {
-
 
199
                        ssd1306_command(0x14);
-
 
200
                }
-
 
201
                ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
-
 
202
                ssd1306_command(0x00);                            // 0x0 act like ks0108
-
 
203
                ssd1306_command(SSD1306_SEGREMAP | 0x1);
-
 
204
                ssd1306_command(SSD1306_COMSCANDEC);
-
 
205
                ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
-
 
206
                ssd1306_command(0x12);
-
 
207
                ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
-
 
208
                if (vccstate == SSD1306_EXTERNALVCC) {
-
 
209
                        ssd1306_command(0x9F);
-
 
210
                } else {
-
 
211
                        ssd1306_command(0xCF);
-
 
212
                }
-
 
213
                ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
-
 
214
                if (vccstate == SSD1306_EXTERNALVCC) {
-
 
215
                        ssd1306_command(0x22);
-
 
216
                } else {
-
 
217
                        ssd1306_command(0xF1);
-
 
218
                }
-
 
219
                ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
-
 
220
                ssd1306_command(0x40);
-
 
221
                ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
-
 
222
                ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
-
 
223
#endif
154
 
224
 
155
  // VDD (3.3V) goes high at start, lets just chill for a ms
-
 
156
  HAL_Delay(1);
-
 
157
  // bring reset low
-
 
158
  HAL_GPIO_WritePin(SPI_RESET_GPIO_Port,SPI_RESET_Pin,GPIO_PIN_RESET);
-
 
159
  // wait 10ms
-
 
160
  HAL_Delay(10);
-
 
161
  // bring out of reset
-
 
162
  HAL_GPIO_WritePin(SPI_RESET_GPIO_Port,SPI_RESET_Pin,GPIO_PIN_SET);
-
 
163
  // turn on VCC (9V?)
-
 
164
 
-
 
165
  for(cd = 0; cd<2 ; cd++)
-
 
166
  {
-
 
167
   #if defined SSD1306_128_32
-
 
168
    // Init sequence for 128x32 OLED module
-
 
169
    ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
-
 
170
    ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
-
 
171
    ssd1306_command(0x80);                                  // the suggested ratio 0x80
-
 
172
    ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
-
 
173
    ssd1306_command(0x1F);
-
 
174
    ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
-
 
175
    ssd1306_command(0x0);                                   // no offset
-
 
176
    ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
-
 
177
    ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
-
 
178
    if (vccstate == SSD1306_EXTERNALVCC)
-
 
179
      { ssd1306_command(0x10); }
-
 
180
    else
-
 
181
      { ssd1306_command(0x14); }
-
 
182
    ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
-
 
183
    ssd1306_command(0x00);                                  // 0x0 act like ks0108
-
 
184
        ssd1306_command(SSD1306_SEGREMAP | 0x1);
-
 
185
    ssd1306_command(SSD1306_COMSCANDEC);
-
 
186
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
-
 
187
    ssd1306_command(0x02);
-
 
188
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
-
 
189
    ssd1306_command(0x8F);
-
 
190
    ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
-
 
191
    if (vccstate == SSD1306_EXTERNALVCC)
-
 
192
      { ssd1306_command(0x22); }
-
 
193
    else
-
 
194
      { ssd1306_command(0xF1); }
-
 
195
    ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
-
 
196
    ssd1306_command(0x40);
-
 
197
    ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
-
 
198
    ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
-
 
199
  #endif
-
 
200
 
-
 
201
  #if defined SSD1306_128_64
-
 
202
    // Init sequence for 128x64 OLED module
-
 
203
    ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
-
 
204
    ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
-
 
205
    ssd1306_command(0x80);                                  // the suggested ratio 0x80
-
 
206
    ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
-
 
207
    ssd1306_command(0x3F);
-
 
208
    ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
-
 
209
    ssd1306_command(0x0);                                   // no offset
-
 
210
    ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
-
 
211
    ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
-
 
212
    if (vccstate == SSD1306_EXTERNALVCC)
-
 
213
      { ssd1306_command(0x10); }
-
 
214
    else
-
 
215
      { ssd1306_command(0x14); }
-
 
216
    ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
-
 
217
    ssd1306_command(0x00);                                  // 0x0 act like ks0108
-
 
218
    ssd1306_command(SSD1306_SEGREMAP | 0x1);
-
 
219
    ssd1306_command(SSD1306_COMSCANDEC);
-
 
220
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
-
 
221
    ssd1306_command(0x12);
-
 
222
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
-
 
223
    if (vccstate == SSD1306_EXTERNALVCC)
-
 
224
      { ssd1306_command(0x9F); }
-
 
225
    else
-
 
226
      { ssd1306_command(0xCF); }
-
 
227
    ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
-
 
228
    if (vccstate == SSD1306_EXTERNALVCC)
-
 
229
      { ssd1306_command(0x22); }
-
 
230
    else
-
 
231
      { ssd1306_command(0xF1); }
-
 
232
    ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
-
 
233
    ssd1306_command(0x40);
-
 
234
    ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
-
 
235
    ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
-
 
236
  #endif
-
 
237
 
-
 
238
  ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
225
                ssd1306_command(SSD1306_DISPLAYON);               //--turn on oled panel
239
  }
226
        }
240
}
227
}
241
 
228
 
242
 
-
 
243
void invertDisplay(uint8_t i) {
229
void invertDisplay(uint8_t i) {
244
  if (i) {
230
        if (i) {
245
    ssd1306_command(SSD1306_INVERTDISPLAY);
231
                ssd1306_command(SSD1306_INVERTDISPLAY);
246
  } else {
232
        } else {
247
    ssd1306_command(SSD1306_NORMALDISPLAY);
233
                ssd1306_command(SSD1306_NORMALDISPLAY);
248
  }
234
        }
249
}
235
}
250
 
236
 
251
void ssd1306_command(uint8_t c)
237
void ssd1306_command(uint8_t c) {
252
{
-
 
253
        HAL_GPIO_WritePin(SPI1CD_GPIO_Port,SPI1CD_Pin,GPIO_PIN_RESET);
238
        HAL_GPIO_WritePin(SPI1CD_GPIO_Port, SPI1CD_Pin, GPIO_PIN_RESET);
254
 
239
 
255
    fastSPIwrite(c);
240
        fastSPIwrite(c);
256
 
241
 
257
}
242
}
258
 
243
 
259
// startscrollright
244
// startscrollright
260
// Activate a right handed scroll for rows start through stop
245
// Activate a right handed scroll for rows start through stop
261
// Hint, the display is 16 rows tall. To scroll the whole display, run:
246
// Hint, the display is 16 rows tall. To scroll the whole display, run:
262
// display.scrollright(0x00, 0x0F) 
247
// display.scrollright(0x00, 0x0F) 
263
void startscrollright(uint8_t start, uint8_t stop){
248
void startscrollright(uint8_t start, uint8_t stop) {
264
        ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL);
249
        ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL);
265
        ssd1306_command(0X00);
250
        ssd1306_command(0X00);
266
        ssd1306_command(start);
251
        ssd1306_command(start);
267
        ssd1306_command(0X00);
252
        ssd1306_command(0X00);
268
        ssd1306_command(stop);
253
        ssd1306_command(stop);
Line 273... Line 258...
273
 
258
 
274
// startscrollleft
259
// startscrollleft
275
// Activate a right handed scroll for rows start through stop
260
// Activate a right handed scroll for rows start through stop
276
// Hint, the display is 16 rows tall. To scroll the whole display, run:
261
// Hint, the display is 16 rows tall. To scroll the whole display, run:
277
// display.scrollright(0x00, 0x0F) 
262
// display.scrollright(0x00, 0x0F) 
278
void startscrollleft(uint8_t start, uint8_t stop){
263
void startscrollleft(uint8_t start, uint8_t stop) {
279
        ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL);
264
        ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL);
280
        ssd1306_command(0X00);
265
        ssd1306_command(0X00);
281
        ssd1306_command(start);
266
        ssd1306_command(start);
282
        ssd1306_command(0X00);
267
        ssd1306_command(0X00);
283
        ssd1306_command(stop);
268
        ssd1306_command(stop);
Line 288... Line 273...
288
 
273
 
289
// startscrolldiagright
274
// startscrolldiagright
290
// Activate a diagonal scroll for rows start through stop
275
// Activate a diagonal scroll for rows start through stop
291
// Hint, the display is 16 rows tall. To scroll the whole display, run:
276
// Hint, the display is 16 rows tall. To scroll the whole display, run:
292
// display.scrollright(0x00, 0x0F) 
277
// display.scrollright(0x00, 0x0F) 
293
void startscrolldiagright(uint8_t start, uint8_t stop){
278
void startscrolldiagright(uint8_t start, uint8_t stop) {
294
        ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);     
279
        ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
295
        ssd1306_command(0X00);
280
        ssd1306_command(0X00);
296
        ssd1306_command(SSD1306_LCDHEIGHT);
281
        ssd1306_command(SSD1306_LCDHEIGHT);
297
        ssd1306_command(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
282
        ssd1306_command(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
298
        ssd1306_command(0X00);
283
        ssd1306_command(0X00);
299
        ssd1306_command(start);
284
        ssd1306_command(start);
Line 305... Line 290...
305
 
290
 
306
// startscrolldiagleft
291
// startscrolldiagleft
307
// Activate a diagonal scroll for rows start through stop
292
// Activate a diagonal scroll for rows start through stop
308
// Hint, the display is 16 rows tall. To scroll the whole display, run:
293
// Hint, the display is 16 rows tall. To scroll the whole display, run:
309
// display.scrollright(0x00, 0x0F) 
294
// display.scrollright(0x00, 0x0F) 
310
void startscrolldiagleft(uint8_t start, uint8_t stop){
295
void startscrolldiagleft(uint8_t start, uint8_t stop) {
311
        ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);     
296
        ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
312
        ssd1306_command(0X00);
297
        ssd1306_command(0X00);
313
        ssd1306_command(SSD1306_LCDHEIGHT);
298
        ssd1306_command(SSD1306_LCDHEIGHT);
314
        ssd1306_command(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
299
        ssd1306_command(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
315
        ssd1306_command(0X00);
300
        ssd1306_command(0X00);
316
        ssd1306_command(start);
301
        ssd1306_command(start);
Line 318... Line 303...
318
        ssd1306_command(stop);
303
        ssd1306_command(stop);
319
        ssd1306_command(0X01);
304
        ssd1306_command(0X01);
320
        ssd1306_command(SSD1306_ACTIVATE_SCROLL);
305
        ssd1306_command(SSD1306_ACTIVATE_SCROLL);
321
}
306
}
322
 
307
 
323
void stopscroll(void){
308
void stopscroll(void) {
324
        ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
309
        ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
325
}
310
}
326
 
311
 
327
// Dim the display
312
// Dim the display
328
// dim = true: display is dimmed
313
// dim = true: display is dimmed
329
// dim = false: display is normal
314
// dim = false: display is normal
330
void dim(boolean dim) {
315
void dim(uint8_t dim) {
331
  uint8_t contrast;
316
        uint8_t contrast;
332
 
317
 
333
  if (dim) {
318
        if (dim) {
334
    contrast = 0; // Dimmed display
319
                contrast = 0; // Dimmed display
335
  } else {
320
        } else {
336
      contrast = 0xCF;
321
                contrast = 0xCF;
337
  }
322
        }
338
  // the range of contrast to too small to be really useful
323
        // the range of contrast to too small to be really useful
339
  // it is useful to dim the display
324
        // it is useful to dim the display
340
  ssd1306_command(SSD1306_SETCONTRAST);
325
        ssd1306_command(SSD1306_SETCONTRAST);
341
  ssd1306_command(contrast);
326
        ssd1306_command(contrast);
342
}
327
}
343
 
328
 
344
void display(void) {
329
void display(void) {
345
  ssd1306_command(SSD1306_COLUMNADDR);
330
        ssd1306_command(SSD1306_COLUMNADDR);
346
  ssd1306_command(0);   // Column start address (0 = reset)
331
        ssd1306_command(0);   // Column start address (0 = reset)
347
  ssd1306_command(131); // Column end address (127 = reset)
332
        ssd1306_command(131); // Column end address (127 = reset)
348
 
333
 
349
  ssd1306_command(SSD1306_PAGEADDR);
334
        ssd1306_command(SSD1306_PAGEADDR);
350
  ssd1306_command(0); // Page start address (0 = reset)
335
        ssd1306_command(0); // Page start address (0 = reset)
351
  ssd1306_command((SSD1306_LCDHEIGHT == 64) ? 7 : 3); // Page end address
336
        ssd1306_command((SSD1306_LCDHEIGHT == 64) ? 7 : 3); // Page end address
352
 
337
 
353
  int row;
338
        int row;
354
  int col=2;
339
        int col = 2;
355
  for(row=0;row<SSD1306_LCDHEIGHT/8;row++)
340
        for (row = 0; row < SSD1306_LCDHEIGHT / 8; row++) {
356
  {
-
 
357
     // set the cursor to
341
                // set the cursor to
358
          ssd1306_command(0xB0 + row);//set page address
342
                ssd1306_command(0xB0 + row); //set page address
359
          ssd1306_command(col & 0xf);//set lower column address
343
                ssd1306_command(col & 0xf); //set lower column address
360
          ssd1306_command(0x10 | (col >> 4));//set higher column address
344
                ssd1306_command(0x10 | (col >> 4)); //set higher column address
361
 
-
 
362
 
345
 
363
      HAL_GPIO_WritePin(SPI1CD_GPIO_Port,SPI1CD_Pin,GPIO_PIN_SET);
346
                HAL_GPIO_WritePin(SPI1CD_GPIO_Port, SPI1CD_Pin, GPIO_PIN_SET);
-
 
347
                HAL_SPI_Transmit(&hspi1,
364
      HAL_SPI_Transmit(&hspi1, (uint8_t *)(&display_buffer[cd])+row*SSD1306_LCDWIDTH, SSD1306_LCDWIDTH, 100);
348
                                (uint8_t *) (&display_buffer[cd]) + row * SSD1306_LCDWIDTH,
-
 
349
                                SSD1306_LCDWIDTH, 100);
365
      }
350
        }
366
 
351
 
367
}
352
}
368
 
353
 
369
 
-
 
370
// clear everything
354
// clear everything
371
void clearDisplay(void) {
355
void clearDisplay(void) {
372
  memset(&display_buffer[cd], 0, (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8));
356
        memset(&display_buffer[cd], 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
373
}
357
}
374
 
358
 
375
 
-
 
376
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
359
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
377
  boolean bSwap = false;
360
        boolean bSwap = false;
378
  switch(rotation) {
361
        switch (rotation) {
379
    case 0:
362
        case 0:
380
      // 0 degree rotation, do nothing
363
                // 0 degree rotation, do nothing
381
      break;
364
                break;
382
    case 1:
365
        case 1:
383
      // 90 degree rotation, swap x & y for rotation, then invert x
366
                // 90 degree rotation, swap x & y for rotation, then invert x
384
      bSwap = true;
367
                bSwap = true;
385
      swap(x, y);
368
                swap(x, y)
-
 
369
                ;
386
      x = WIDTH - x - 1;
370
                x = WIDTH - x - 1;
387
      break;
371
                break;
388
    case 2:
372
        case 2:
389
      // 180 degree rotation, invert x and y - then shift y around for height.
373
                // 180 degree rotation, invert x and y - then shift y around for height.
390
      x = WIDTH - x - 1;
374
                x = WIDTH - x - 1;
391
      y = HEIGHT - y - 1;
375
                y = HEIGHT - y - 1;
392
      x -= (w-1);
376
                x -= (w - 1);
393
      break;
377
                break;
394
    case 3:
378
        case 3:
395
      // 270 degree rotation, swap x & y for rotation, then invert y  and adjust y for w (not to become h)
379
                // 270 degree rotation, swap x & y for rotation, then invert y  and adjust y for w (not to become h)
396
      bSwap = true;
380
                bSwap = true;
397
      swap(x, y);
381
                swap(x, y)
-
 
382
                ;
398
      y = HEIGHT - y - 1;
383
                y = HEIGHT - y - 1;
399
      y -= (w-1);
384
                y -= (w - 1);
400
      break;
385
                break;
401
  }
386
        }
402
 
387
 
403
  if(bSwap) {
388
        if (bSwap) {
404
    drawFastVLineInternal(x, y, w, color);
389
                drawFastVLineInternal(x, y, w, color);
405
  } else {
390
        } else {
406
    drawFastHLineInternal(x, y, w, color);
391
                drawFastHLineInternal(x, y, w, color);
407
  }
392
        }
408
}
393
}
409
 
394
 
410
void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) {
395
void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) {
411
  // Do bounds/limit checks
396
        // Do bounds/limit checks
412
  if(y < 0 || y >= HEIGHT) { return; }
397
        if (y < 0 || y >= HEIGHT) {
-
 
398
                return;
-
 
399
        }
-
 
400
 
-
 
401
        // make sure we don't try to draw below 0
-
 
402
        if (x < 0) {
-
 
403
                w += x;
-
 
404
                x = 0;
-
 
405
        }
413
 
406
 
414
  // make sure we don't try to draw below 0
-
 
415
  if(x < 0) {
-
 
416
    w += x;
-
 
417
    x = 0;
-
 
418
  }
-
 
419
 
-
 
420
  // make sure we don't go off the edge of the display
407
        // make sure we don't go off the edge of the display
421
  if( (x + w) > WIDTH) {
408
        if ((x + w) > WIDTH) {
422
    w = (HEIGHT- x);
409
                w = (HEIGHT - x);
423
  }
410
        }
424
 
411
 
425
  // if our width is now negative, punt
412
        // if our width is now negative, punt
426
  if(w <= 0) { return; }
413
        if (w <= 0) {
-
 
414
                return;
-
 
415
        }
427
 
416
 
428
  // set up the pointer for  movement through the buffer
417
        // set up the pointer for  movement through the buffer
429
  register uint8_t *pBuf = display_address();
418
        register uint8_t *pBuf = display_address();
430
  // adjust the buffer pointer for the current row
419
        // adjust the buffer pointer for the current row
431
  pBuf += ((y/8) * SSD1306_LCDWIDTH);
420
        pBuf += ((y / 8) * SSD1306_LCDWIDTH);
432
  // and offset x columns in
421
        // and offset x columns in
433
  pBuf += x;
422
        pBuf += x;
434
 
423
 
435
  register uint8_t mask = 1 << (y&7);
424
        register uint8_t mask = 1 << (y & 7);
436
 
425
 
437
  if(color == WHITE) {
426
        if (color == WHITE) {
-
 
427
                while (w--) {
438
    while(w--) { *pBuf++ |= mask; }
428
                        *pBuf++ |= mask;
-
 
429
                }
439
  } else {
430
        } else {
440
    mask = ~mask;
431
                mask = ~mask;
-
 
432
                while (w--) {
441
    while(w--) { *pBuf++ &= mask; }
433
                        *pBuf++ &= mask;
442
  }
434
                }
-
 
435
        }
443
}
436
}
444
 
437
 
445
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
438
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
446
  boolean bSwap = false;
439
        boolean bSwap = false;
447
  switch(rotation) {
440
        switch (rotation) {
448
    case 0:
441
        case 0:
449
      break;
442
                break;
450
    case 1:
443
        case 1:
451
      // 90 degree rotation, swap x & y for rotation, then invert x and adjust x for h (now to become w)
444
                // 90 degree rotation, swap x & y for rotation, then invert x and adjust x for h (now to become w)
452
      bSwap = true;
445
                bSwap = true;
453
      swap(x, y);
446
                swap(x, y)
-
 
447
                ;
454
      x = WIDTH - x - 1;
448
                x = WIDTH - x - 1;
455
      x -= (h-1);
449
                x -= (h - 1);
456
      break;
450
                break;
457
    case 2:
451
        case 2:
458
      // 180 degree rotation, invert x and y - then shift y around for height.
452
                // 180 degree rotation, invert x and y - then shift y around for height.
459
      x = WIDTH - x - 1;
453
                x = WIDTH - x - 1;
460
      y = HEIGHT - y - 1;
454
                y = HEIGHT - y - 1;
461
      y -= (h-1);
455
                y -= (h - 1);
462
      break;
456
                break;
463
    case 3:
457
        case 3:
464
      // 270 degree rotation, swap x & y for rotation, then invert y 
458
                // 270 degree rotation, swap x & y for rotation, then invert y
465
      bSwap = true;
459
                bSwap = true;
466
      swap(x, y);
460
                swap(x, y)
467
      y = HEIGHT - y - 1;
-
 
468
      break;
-
 
469
  }
461
                ;
470
 
-
 
471
  if(bSwap) {
462
                y = HEIGHT - y - 1;
472
    drawFastHLineInternal(x, y, h, color);
-
 
473
  } else {
463
                break;
474
    drawFastVLineInternal(x, y, h, color);
-
 
475
  }
-
 
476
}
464
        }
477
 
465
 
-
 
466
        if (bSwap) {
-
 
467
                drawFastHLineInternal(x, y, h, color);
-
 
468
        } else {
-
 
469
                drawFastVLineInternal(x, y, h, color);
-
 
470
        }
-
 
471
}
478
 
472
 
479
void drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color) {
473
void drawFastVLineInternal(int16_t x, int16_t __y, int16_t __h, uint16_t color) {
480
 
474
 
481
  // do nothing if we're off the left or right side of the screen
475
        // do nothing if we're off the left or right side of the screen
482
  if(x < 0 || x >= WIDTH) { return; }
476
        if (x < 0 || x >= WIDTH) {
-
 
477
                return;
-
 
478
        }
483
 
479
 
484
  // make sure we don't try to draw below 0
480
        // make sure we don't try to draw below 0
485
  if(__y < 0) {
481
        if (__y < 0) {
486
    // __y is negative, this will subtract enough from __h to account for __y being 0
482
                // __y is negative, this will subtract enough from __h to account for __y being 0
487
    __h += __y;
483
                __h += __y;
488
    __y = 0;
484
                __y = 0;
489
 
485
 
490
  }
486
        }
491
 
487
 
492
  // make sure we don't go past the height of the display
488
        // make sure we don't go past the height of the display
493
  if( (__y + __h) > HEIGHT) {
489
        if ((__y + __h) > HEIGHT) {
494
    __h = (HEIGHT - __y);
490
                __h = (HEIGHT - __y);
495
  }
-
 
496
 
-
 
497
  // if our height is now negative, punt 
-
 
498
  if(__h <= 0) {
-
 
499
    return;
-
 
500
  }
-
 
501
 
-
 
502
  // this display doesn't need ints for coordinates, use local byte registers for faster juggling
-
 
503
  register uint8_t y = __y;
-
 
504
  register uint8_t h = __h;
-
 
505
 
-
 
506
 
-
 
507
  // set up the pointer for fast movement through the buffer
-
 
508
  register uint8_t *pBuf = display_address();
-
 
509
  // adjust the buffer pointer for the current row
-
 
510
  pBuf += ((y/8) * SSD1306_LCDWIDTH);
-
 
511
  // and offset x columns in
-
 
512
  pBuf += x;
-
 
513
 
-
 
514
  // do the first partial byte, if necessary - this requires some masking
-
 
515
  register uint8_t mod = (y&7);
-
 
516
  if(mod) {
-
 
517
    // mask off the high n bits we want to set 
-
 
518
    mod = 8-mod;
-
 
519
 
-
 
520
    // note - lookup table results in a nearly 10% performance improvement in fill* functions
-
 
521
    // register uint8_t mask = ~(0xFF >> (mod));
-
 
522
    static uint8_t premask[8] = {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
-
 
523
    register uint8_t mask = premask[mod];
-
 
524
 
-
 
525
    // adjust the mask if we're not going to reach the end of this byte
-
 
526
    if( h < mod) {
-
 
527
      mask &= (0XFF >> (mod-h));
-
 
528
    }
-
 
529
 
-
 
530
    if(color == WHITE) {
-
 
531
      *pBuf |= mask;
-
 
532
    } else {
-
 
533
      *pBuf &= ~mask;
-
 
534
    }
-
 
535
 
-
 
536
    // fast exit if we're done here!
-
 
537
    if(h<mod) { return; }
-
 
538
 
-
 
539
    h -= mod;
-
 
540
 
-
 
541
    pBuf += SSD1306_LCDWIDTH;
-
 
542
  }
-
 
543
 
-
 
544
 
-
 
545
  // write solid bytes while we can - effectively doing 8 rows at a time
-
 
546
  if(h >= 8) {
-
 
547
    // store a local value to work with 
-
 
548
    register uint8_t val = (color == WHITE) ? 255 : 0;
-
 
549
 
-
 
550
    do  {
-
 
551
      // write our value in
-
 
552
      *pBuf = val;
-
 
553
 
-
 
554
      // adjust the buffer forward 8 rows worth of data
-
 
555
      pBuf += SSD1306_LCDWIDTH;
-
 
556
 
-
 
557
      // adjust h & y (there's got to be a faster way for me to do this, but this should still help a fair bit for now)
-
 
558
      h -= 8;
-
 
559
    } while(h >= 8);
-
 
560
  }
-
 
561
 
-
 
562
  // now do the final partial byte, if necessary
-
 
563
  if(h) {
-
 
564
    mod = h & 7;
-
 
565
    // this time we want to mask the low bits of the byte, vs the high bits we did above
-
 
566
    // register uint8_t mask = (1 << mod) - 1;
-
 
567
    // note - lookup table results in a nearly 10% performance improvement in fill* functions
-
 
568
    static uint8_t postmask[8] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
-
 
569
    register uint8_t mask = postmask[mod];
-
 
570
    if(color == WHITE) {
-
 
571
      *pBuf |= mask;
-
 
572
    } else {
-
 
573
      *pBuf &= ~mask;
-
 
574
    }
-
 
575
  }
-
 
576
}
491
        }
577
 
492
 
-
 
493
        // if our height is now negative, punt
-
 
494
        if (__h <= 0) {
-
 
495
                return;
-
 
496
        }
578
 
497
 
-
 
498
        // this display doesn't need ints for coordinates, use local byte registers for faster juggling
-
 
499
        register uint8_t y = __y;
-
 
500
        register uint8_t h = __h;
-
 
501
 
-
 
502
        // set up the pointer for fast movement through the buffer
-
 
503
        register uint8_t *pBuf = display_address();
-
 
504
        // adjust the buffer pointer for the current row
-
 
505
        pBuf += ((y / 8) * SSD1306_LCDWIDTH);
-
 
506
        // and offset x columns in
-
 
507
        pBuf += x;
-
 
508
 
-
 
509
        // do the first partial byte, if necessary - this requires some masking
-
 
510
        register uint8_t mod = (y & 7);
-
 
511
        if (mod) {
-
 
512
                // mask off the high n bits we want to set
-
 
513
                mod = 8 - mod;
-
 
514
 
-
 
515
                // note - lookup table results in a nearly 10% performance improvement in fill* functions
-
 
516
                // register uint8_t mask = ~(0xFF >> (mod));
-
 
517
                static uint8_t premask[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC,
-
 
518
                                0xFE };
-
 
519
                register uint8_t mask = premask[mod];
-
 
520
 
-
 
521
                // adjust the mask if we're not going to reach the end of this byte
-
 
522
                if (h < mod) {
-
 
523
                        mask &= (0XFF >> (mod - h));
-
 
524
                }
579
 
525
 
-
 
526
                if (color == WHITE) {
-
 
527
                        *pBuf |= mask;
-
 
528
                } else {
-
 
529
                        *pBuf &= ~mask;
-
 
530
                }
580
 
531
 
581
/* using Bresenham draw algorithm */
532
                // fast exit if we're done here!
-
 
533
                if (h < mod) {
-
 
534
                        return;
-
 
535
                }
-
 
536
 
-
 
537
                h -= mod;
-
 
538
 
582
void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color)
539
                pBuf += SSD1306_LCDWIDTH;
-
 
540
        }
583
{
541
 
-
 
542
        // write solid bytes while we can - effectively doing 8 rows at a time
584
        int16_t x,
543
        if (h >= 8) {
-
 
544
                // store a local value to work with
-
 
545
                register uint8_t val = (color == WHITE) ? 255 : 0;
-
 
546
 
585
                        y,
547
                do {
-
 
548
                        // write our value in
586
                        dx,             //deltas
549
                        *pBuf = val;
-
 
550
 
-
 
551
                        // adjust the buffer forward 8 rows worth of data
-
 
552
                        pBuf += SSD1306_LCDWIDTH;
-
 
553
 
-
 
554
                        // adjust h & y (there's got to be a faster way for me to do this, but this should still help a fair bit for now)
-
 
555
                        h -= 8;
587
            dy,
556
                } while (h >= 8);
-
 
557
        }
-
 
558
 
588
            dx2,        //scaled deltas
559
        // now do the final partial byte, if necessary
-
 
560
        if (h) {
589
            dy2,
561
                mod = h & 7;
590
            ix,         //increase rate on the x axis
562
                // this time we want to mask the low bits of the byte, vs the high bits we did above
591
            iy,         //increase rate on the y axis
563
                // register uint8_t mask = (1 << mod) - 1;
-
 
564
                // note - lookup table results in a nearly 10% performance improvement in fill* functions
-
 
565
                static uint8_t postmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F,
-
 
566
                                0x7F };
592
            err;        //the error term
567
                register uint8_t mask = postmask[mod];
593
    uint16_t i;         //looping variable
568
                if (color == WHITE) {
-
 
569
                        *pBuf |= mask;
-
 
570
                } else {
-
 
571
                        *pBuf &= ~mask;
-
 
572
                }
-
 
573
        }
-
 
574
}
594
 
575
 
-
 
576
/* using Bresenham draw algorithm */
-
 
577
void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t color) {
-
 
578
        int16_t x, y, dx,               //deltas
-
 
579
                        dy, dx2,        //scaled deltas
-
 
580
                        dy2, ix,                //increase rate on the x axis
-
 
581
                        iy,             //increase rate on the y axis
-
 
582
                        err;    //the error term
-
 
583
        uint16_t i;             //looping variable
595
 
584
 
596
        // identify the first pixel
585
        // identify the first pixel
597
        x=x1;
586
        x = x1;
598
        y=y1;
587
        y = y1;
599
 
588
 
600
        // difference between starting and ending points
589
        // difference between starting and ending points
601
        dx = x2 - x1;
590
        dx = x2 - x1;
602
        dy = y2 - y1;
591
        dy = y2 - y1;
603
 
592
 
604
        // calculate direction of the vector and store in ix and iy
593
        // calculate direction of the vector and store in ix and iy
605
        if (dx >= 0)
594
        if (dx >= 0)
606
                ix = 1;
595
                ix = 1;
607
 
596
 
608
        if (dx < 0)
597
        if (dx < 0) {
609
        {
-
 
610
                ix = -1;
598
                ix = -1;
611
                dx = abs(dx);
599
                dx = abs(dx);
612
        }
600
        }
613
 
601
 
614
        if (dy >= 0)
602
        if (dy >= 0)
615
                iy = 1;
603
                iy = 1;
616
 
604
 
617
        if (dy < 0)
605
        if (dy < 0) {
618
        {
-
 
619
                iy = -1;
606
                iy = -1;
620
                dy = abs(dy);
607
                dy = abs(dy);
621
        }
608
        }
622
 
609
 
623
        // scale deltas and store in dx2 and dy2
610
        // scale deltas and store in dx2 and dy2
Line 625... Line 612...
625
        dy2 = dy * 2;
612
        dy2 = dy * 2;
626
 
613
 
627
// all  variables are set and it's time to enter the main loop.
614
// all  variables are set and it's time to enter the main loop.
628
 
615
 
629
        if (dx > dy)    // dx is the major axis
616
        if (dx > dy)    // dx is the major axis
630
        {
617
                        {
631
                // initialize the error term
618
                // initialize the error term
632
                err = dy2 - dx;
619
                err = dy2 - dx;
633
 
620
 
634
                for (i = 0; i <= dx; i++)
621
                for (i = 0; i <= dx; i++) {
635
                {
-
 
636
                        drawPixel(x, y, color);
622
                        drawPixel(x, y, color);
637
                        if (err >= 0)
623
                        if (err >= 0) {
638
                        {
-
 
639
                                err -= dx2;
624
                                err -= dx2;
640
                                y += iy;
625
                                y += iy;
641
                        }
626
                        }
642
                        err += dy2;
627
                        err += dy2;
643
                        x += ix;
628
                        x += ix;
Line 647... Line 632...
647
        else            // dy is the major axis
632
        else            // dy is the major axis
648
        {
633
        {
649
                // initialize the error term
634
                // initialize the error term
650
                err = dx2 - dy;
635
                err = dx2 - dy;
651
 
636
 
652
                for (i = 0; i <= dy; i++)
637
                for (i = 0; i <= dy; i++) {
653
                {
-
 
654
                        drawPixel(x, y, color);
638
                        drawPixel(x, y, color);
655
                        if (err >= 0)
639
                        if (err >= 0) {
656
                        {
-
 
657
                                err -= dy2;
640
                                err -= dy2;
658
                                x += ix;
641
                                x += ix;
659
                        }
642
                        }
660
                        err += dx2;
643
                        err += dx2;
661
                        y += iy;
644
                        y += iy;
662
                }
645
                }
663
        }
646
        }
664
}
647
}
665
 
648
 
666
 
-
 
667
void select_display(int i)
649
void select_display(int i) {
668
{
-
 
669
        if(i<MAX_PHYS_DISPLAYS)
650
        if (i < MAX_PHYS_DISPLAYS) {
670
        {
-
 
671
                cd = i;
651
                cd = i;
672
        }
652
        }
673
}
653
}