PIC24_DOG
ea_dog_mio.txt.c
gehe zur Dokumentation dieser Datei
1 /*
2  * file: EA-DOGM_MIO.c
3  * version: 2.03
4  * description: Multi I/O driver for EA DOGM displays
5  * : Uses 8Bit, SPI HW or SPI SW (bitbang)
6  * written by : Michael Bradley (mbradley@mculabs.com)
7  * contributions: Imaginos (CCS forum), Emil Nad (8Bit testing)
8  * jgschmidt (CCS forum)
9  *
10  * Changelog:
11  * 04/22/2010 v2.03 Minor update, changed EADOGM_SPI_HW for HW SPI 1 and 2
12  * Added setup_spi() for HW SPI use, and spi_clk_div option
13  * thanks to jgschmidt (ccs forum) for noticing hw setup issues
14  * 12/03/2009 v2.02 bug fix and printChr change, no user change needed for use
15  * 11/25/2009 v2.01 Minor changes, replaced some functions with macros
16  * 09/17/2009 v2.00 Major change, IO is now 8Bit or SPI (hw or sw)
17  * rewrote some defines as related to pins
18  * 09/15/2009 v1.13 added function eaDogM_WriteIntAtPos()
19  * and eaDogM_WriteStringAtPos()
20  * added some defines to clean source
21  * 08/28/2009 v1.12 EADOGM_COLSPAN defined internally, allowing for
22  * 162 model to position correctly (noted by Imaginos, CCS forum)
23  * Added support for 2nd SPI HW port (suggested by Imaginos, CCS forum)
24  * defined a few more special chr's
25  * 07/12/2009 v1.11 Fixed #define error surrounding BB SPI ini
26  * added eaDogM_ClearRow(row);
27  * 07/11/2009 Created/Consolidated this file from my testing sets
28  *
29  * Usage:
30  * In your source, you need to define which EA DOGM display you are using,
31  * there are 3 units supported EADOGM081 , EADOGM162 , EADOGM163 To use
32  * define with a 1.
33  *
34  * #define EADOGM081 1 // to use MODEL EADOG081
35  * #define EADOGM162 1 // to use MODEL EADOG162
36  * #define EADOGM163 1 // to use MODEL EADOG163
37  * #define EADOGMVDD 5 // 5v LCD Vdd
38  * #define EADOGMVDD 3 // 3.3v LCD Vdd
39  *
40  *
41  * // we need to define the IO mode we want, select only one of these, set to 1
42  * #define EADOGM_SPI_HW 1 // hw spi, uses on chip spi
43  * #define EADOGM_SPI_HW 2 // hw spi, 2nd on chip spi
44  * #define EADOGM_SPI_DIV SPI_CLK_DIV_64 // used to slow hw spi clock (you can use other constants)
45  * #define EADOGM_SPI_SW 1 // sw bit bang, can use any io pins
46  * #define EADOGM_8BIT 1 // 8 bit data bus
47  *
48  * // for 8Bit mode only, we need to define the output port
49  * // however, this can be our own function if need be.
50  * // example shows output to port b
51  * #define EADOGM_8BIT_PORT(d) output_b(d); // we need to define how the byte goes out
52  * //#define EADOGM_8BIT_PORT(d) your_func(d); // we need to define how the byte goes out
53  *
54  *
55  * // we need to define a few pins
56  * #define EADOGM_PIN_RS PIN_C1 // RS line, (pin 39 on the LCD)
57  * #define EADOGM_PIN_CSB PIN_C2 // /CSB line, (pin 38 on the LCD) Req for SPI Opt for 8BIT
58  *
59  * // for 8 bit mode, we need to define a few more pins
60  * #define EADOGM_NOCSB 1 // set to 1 if pin 38 (CSB) on lcd is tied to Vss
61  * #define EADOGM_PIN_E PIN_C2 // E (pin 36 on the LCD)
62  * #define EADOGM_PIN_RW PIN_C6 // RW (pin 37 on the LCD)
63  *
64  * // set these if you are using EADOGM_SPI_SW (bit bang)
65  * #define EADOGM_SCLK_BB PIN_C3 // Connects to pin 29 on LCD
66  * #define EADOGM_MOSI_BB PIN_C5 // Connects to pin 28 on LCD
67  *
68  *
69  *
70  * #include "EA-DOGM_MIO.c"
71  *
72  * In your main code, do an ini call
73  * eaDogM_Initialize();
74  * eaDogM_DisplayOn();
75  *
76  *
77  * Available Functions:
78  * -------------------------------------------------------------------------------
79  * eaDogM_Cls(); // clears the screen, homes cursor
80  * eaDogM_ClearRow(row); // clears a row (v1.11)
81  * eaDogM_CursorOn(); // turns on the cursor
82  * eaDogM_CursorOff(); // turns of the cursor
83  * eaDogM_DisplayOn(); // turns on display with cursor off
84  * eaDogM_DisplayOff(); // turns off display
85  * eaDogM_SetPos(row, col); // sets position row:0-2, col:0-15
86  * eaDogM_WriteChr(byte); // writes a single chr to the display
87  * eaDogM_WriteString(char str); // writes a string to the display
88  * // note: add this line after device selection
89  * // to do this: eaDogM_WriteString("Constant")
90  * // #device PASS_STRINGS=IN_RAM
91  *
92  * // writes a 2 digit integer at row,col set flag = 1 to disable interrupts
93  * eaDogM_WriteIntAtPos(row,col,int[,flag])
94  *
95  * // writes a string at row,col set flag = 1 to disable interrupts
96  * eaDogM_WriteStringAtPos(row,col,char str[,flag])
97  *
98  * eaDogM_SetContrast(c); // set contrast 0 to 15
99  * eaDogM_DoubleHeight(row); // turn on double height, row = 0 or 1
100  * eaDogM_DoubleHeightOff(); // turn off double height
101  * -------------------------------------------------------------------------------
102  *
103  */
104 
105 #define EADOGM163 1
106 #define EADOGMVDD 3
107 #define EADOGM_SPI_HW 1
108 #define EADOGM_PIN_RS LATBbits.LATB14
109 #define EADOGM_PIN_CSB LATBbits.LATB13
110 
111 #ifndef EADOGM_SPI
112  #define EADOGM_SPI 1
113 
114 // some special symbol chrs defined
115 #define EADMSYM_DEG 0b11011111 // degree symbol
116 #define EADMSYM_DARWL 0b11111011 // double <<
117 #define EADMSYM_DARWR 0b11111100 // double >>
118 #define EADMSYM_LT 0b00111100 // less than <
119 #define EADMSYM_GT 0b00111110 // greater than >
120 #define EADMSYM_OHM 0b00011110 // ohm symbol
121 
122 // some command defines
123 #define EADMCMD_CONTRAST 0b0111000 // contrast command (0b0111xxxx)
124 
125 
126 // we noticed some issues with GLOBAL on pic24 devices
127 #ifndef GLOBAL
128  #define GLOBAL INTR_GLOBAL
129 #endif
130 
131 
132 // 1x16
133 #ifdef EADOGM081
134  #define EADOGM_ROWS 1
135  #if EADOGMVDD == 5
136  #define EADOGM_INIT_BIAS_SET 0x1C
137  #define EADOGM_INIT_POWER_CONTROL 0x51
138  #define EADOGM_INIT_FOLLOWER_CONTROL 0x6A
139  #define EADOGM_INIT_CONTRAST_SET 0x74
140  #else
141  #define EADOGM_INIT_BIAS_SET 0x14
142  #define EADOGM_INIT_POWER_CONTROL 0x55
143  #define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
144  #define EADOGM_INIT_CONTRAST_SET 0x7C
145  #endif
146 
147  #define EADOGM_INIT_FS1 0x31
148  #define EADOGM_INIT_FS2 0x30
149  #define EADOGM_INIT_CLEAR_DISPLAY 0x01
150  #define EADOGM_INIT_ENTRY_MODE 0x06
151  #define EADOGM_COLSPAN 16
152 #endif
153 
154 
155 // 2x16
156 #ifdef EADOGM162
157  #define EADOGM_ROWS 2
158  #if EADOGMVDD == 5
159  #define EADOGM_INIT_BIAS_SET 0x1C
160  #define EADOGM_INIT_POWER_CONTROL 0x52
161  #define EADOGM_INIT_FOLLOWER_CONTROL 0x69
162  #define EADOGM_INIT_CONTRAST_SET 0x74
163  #else
164  #define EADOGM_INIT_BIAS_SET 0x14
165  #define EADOGM_INIT_POWER_CONTROL 0x55
166  #define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
167  #define EADOGM_INIT_CONTRAST_SET 0x78
168  #endif
169 
170  #define EADOGM_INIT_FS1 0x39
171  #define EADOGM_INIT_FS2 0x38
172  #define EADOGM_INIT_CLEAR_DISPLAY 0x01
173  #define EADOGM_INIT_ENTRY_MODE 0x06
174  #define EADOGM_COLSPAN 40 // suggested that this be 40 on model 162
175 #endif
176 
177 // 3x16
178 #ifdef EADOGM163
179  #define EADOGM_ROWS 3
180  #if EADOGMVDD == 5
181  #define EADOGM_INIT_BIAS_SET 0x1D
182  #define EADOGM_INIT_POWER_CONTROL 0x50
183  #define EADOGM_INIT_FOLLOWER_CONTROL 0x6C
184  #define EADOGM_INIT_CONTRAST_SET 0x7C
185  #else
186  #define EADOGM_INIT_BIAS_SET 0x15
187  #define EADOGM_INIT_POWER_CONTROL 0x55
188  #define EADOGM_INIT_FOLLOWER_CONTROL 0x6E
189  #define EADOGM_INIT_CONTRAST_SET 0x72
190  #endif
191 
192  #define EADOGM_INIT_FS1 0x39
193  #define EADOGM_INIT_FS2 0x38
194  #define EADOGM_INIT_CLEAR_DISPLAY 0x01
195  #define EADOGM_INIT_ENTRY_MODE 0x06
196  #define EADOGM_COLSPAN 16
197 #endif
198 
199 
200 #define EADOGM_CMD_CLR 1
201 #define EADOGM_CMD_CURSOR_ON 0b00001111
202 #define EADOGM_CMD_CURSOR_OFF 0b00001100
203 #define EADOGM_CMD_DISPLAY_ON 0b00001100
204 #define EADOGM_CMD_DISPLAY_OFF 0b00001000
205 #define EADOGM_CMD_DDRAM_ADDR 0b10000000
206 #define EADOGM_CMD_CGRAM_ADDR 0b01000000
207 #define EADOGM_CMD_SELECT_R0 0b00011000
208 #define EADOGM_CMD_SELECT_R1 0b00010000
209 #define EADOGM_CMD_SET_TABLE2 0b00101010
210 
211 
212 // spi hw clock div, v2.03 fix
213 #ifndef EADOGM_SPI_DIV
214  #define EADOGM_SPI_DIV SPI_CLK_DIV_4
215 #endif
216 
217 
218 
219 // sw spi emulation routine (bit bang)
220 #ifdef EADOGM_SPI_SW
221  #ifndef EADOGM_SCLK_BB
222  #define EADOGM_SCLK_BB PIN_C3
223  #endif
224  #ifndef EADOGM_MOSI_BB
225  #define EADOGM_MOSI_BB PIN_C5
226  #endif
227 
228 
229 void eaDogM_iniSPI_BB(void)
230 {
231  output_drive(EADOGM_SCLK_BB);
232  output_drive(EADOGM_MOSI_BB);
233  output_low(EADOGM_SCLK_BB);
234  output_low(EADOGM_MOSI_BB);
235 }
236 
237 void eaDogM_spiWrite_BB(int8 regData)
238 {
239 
240  int1 bitOut;
241  int8 SPICount; // Counter used to clock out the data
242  int8 SPIData; // Define a data structure for the SPI data.
243 
244  output_low(EADOGM_SCLK_BB); // and CK low
245 
246  SPIData = regData;
247  for (SPICount = 0; SPICount < 8; SPICount++) // Prepare to clock out the Address byte
248  {
249  bitOut = bit_test(SPIData,7);
250  output_bit(EADOGM_MOSI_BB,bitOut);
251  output_high(EADOGM_SCLK_BB); // Toggle the clock line
252  //delay_us(10);
253  output_low(EADOGM_SCLK_BB);
254  //delay_us(10);
255  SPIData = SPIData << 1; // Rotate to get the next bit
256  } // and loop back to send the next bit
257 
258  output_low(EADOGM_MOSI_BB);
259 }
260 
261 // wrapper for sw spi calls in main program
262 // v2.01 moved to macro define
263 #define eaDogM_outSPI(c) eaDogM_spiWrite_BB(c)
264 #endif
265 
266 // wrapper for hw spi calls in main program
267 // v2.01 moved to a macro define
268 #if EADOGM_SPI_HW == 1
269  #define eaDogM_outSPI(c) spi_write(c)
270 #endif
271 
272 // wrapper for hw2 spi calls in main program
273 // v2.01 moved to a macro define, v2.03 using EADOGM_SPI_HW to test condition
274 #if EADOGM_SPI_HW == 2
275  #define eaDogM_outSPI(c) spi_write2(c)
276 #endif
277 
278 
279 #ifdef EADOGM_8BIT
280 void eaDogM_ini8Bit(void)
281 {
282 #ifndef EADOGM_NOCSB
283  output_drive(EADOGM_PIN_CSB);
284  output_high(EADOGM_PIN_CSB);
285 #endif
286  output_drive(EADOGM_PIN_E);
287  output_drive(EADOGM_PIN_RW);
288  output_drive(EADOGM_PIN_RS);
289  output_low(EADOGM_PIN_E);
290  output_low(EADOGM_PIN_RS);
291  output_low(EADOGM_PIN_RW);
292 }
293 #endif
294 
295 
296 
297 #ifdef EADOGM_8BIT
298 // 8bit mode
299 void eaDogM_WriteChr(char value)
300 {
301  output_high(EADOGM_PIN_RS);
302  output_low(EADOGM_PIN_RW);
303  output_low(EADOGM_PIN_E);
304  #ifndef EADOGM_NOCSB
305  output_low(EADOGM_PIN_CSB);
306  #endif
307  output_high(EADOGM_PIN_E);
308  delay_ms(1);
309  EADOGM_8BIT_PORT(value);
310  output_low(EADOGM_PIN_E);
311  delay_ms(1);
312  #ifndef EADOGM_NOCSB
313  output_low(EADOGM_PIN_CSB);
314  #endif
315  delay_ms(1);
316 }
317 
318 void eaDogM_WriteCommand(int8 cmd)
319 {
320  output_low(EADOGM_PIN_RS);
321  output_low(EADOGM_PIN_RW);
322  output_low(EADOGM_PIN_E);
323  #ifndef EADOGM_NOCSB
324  output_low(EADOGM_PIN_CSB);
325  #endif
326  output_high(EADOGM_PIN_E);
327  delay_ms(1);
328  EADOGM_8BIT_PORT(cmd);
329  output_low(EADOGM_PIN_E);
330  delay_ms(1);
331  #ifndef EADOGM_NOCSB
332  output_low(EADOGM_PIN_CSB);
333  #endif
334  delay_ms(1);
335 }
336 #else
337 // spi mode
338 void eaDogM_WriteChr(char value)
339 {
340  output_high(EADOGM_PIN_RS);
341  output_low(EADOGM_PIN_CSB);
342  eaDogM_outSPI(value);
343  output_high(EADOGM_PIN_CSB);
344  delay_ms(1);
345 }
346 
347 void eaDogM_WriteCommand(int8 cmd)
348 {
349  output_low(EADOGM_PIN_RS);
350  output_low(EADOGM_PIN_CSB);
351  eaDogM_outSPI(cmd);
352  output_high(EADOGM_PIN_CSB);
353  delay_ms(1);
354 }
355 #endif
356 
357 
359 {
360 
361 // v2.03 fix
362 #if EADOGM_SPI_HW == 1
363  setup_spi( SPI_MASTER | SPI_H_TO_L | EADOGM_SPI_DIV );
364 #endif
365 
366 // v2.03 fix
367 #if EADOGM_SPI_HW == 2
368  setup_spi2( SPI_MASTER | SPI_H_TO_L | EADOGM_SPI_DIV );
369 #endif
370 
371 #ifdef EADOGM_SPI_SW
372  eaDogM_iniSPI_BB();
373 #endif
374 
375 #ifdef EADOGM_8BIT
376  eaDogM_ini8Bit();
377 #else
378  output_drive(EADOGM_PIN_CSB);
379  output_drive(EADOGM_PIN_RS);
380  output_high(EADOGM_PIN_CSB);
381  output_high(EADOGM_PIN_RS);
382 #endif
383 
384  delay_ms(200);
385 
394 
395 }
396 
397 // sets contrast, call with a value from 0 to 15
398 // we also mask off upper 4 bits from c
399 // v2.01 moved to a macro define
400 #define eaDogM_SetContrast(c) eaDogM_WriteCommand(EADMCMD_CONTRAST + (c & 0b00001111))
401 
402 // only tested on 3 line display at the moment,
403 // thus no constants defined. when fully tested, I will define them
404 void eaDogM_DoubleHeight(int8 row) // row 0 or 1
405 {
406  eaDogM_WriteCommand(EADOGM_CMD_SET_TABLE2); // set instruction table 2
407  if (row == 0) {
408  eaDogM_WriteCommand(EADOGM_CMD_SELECT_R0); // select row 0
409  }
410  if (row == 1) {
411  eaDogM_WriteCommand(EADOGM_CMD_SELECT_R1); // select row 1
412  }
413  eaDogM_WriteCommand(0b00101100); // turns on double line mode
414  // and set instruction table back to 0
415 }
416 
417 // v2.01 moved functions to macros
418 #define eaDogM_DoubleHeightOff() eaDogM_WriteCommand(0b00101000)
419 #define eaDogM_Cls() eaDogM_WriteCommand(EADOGM_CMD_CLR)
420 #define eaDogM_CursorOn() eaDogM_WriteCommand(EADOGM_CMD_CURSOR_ON)
421 #define eaDogM_CursorOff() eaDogM_WriteCommand(EADOGM_CMD_CURSOR_OFF)
422 #define eaDogM_DisplayOn() eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_ON)
423 #define eaDogM_DisplayOff() eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_OFF)
424 
425 
426 void eaDogM_SetPos(int8 r, int8 c)
427 {
428  int8 cmdPos;
429  cmdPos = EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c;
430  eaDogM_WriteCommand(cmdPos);
431 }
432 
433 void eaDogM_ClearRow(int8 r)
434 {
435  int8 i;
436  eaDogM_SetPos(r,0);
437  for(i=0; i<EADOGM_COLSPAN; i++) {
438  eaDogM_WriteChr(' ');
439  }
440 }
441 
442 void eaDogM_WriteString(char *strPtr)
443 {
444  printf(eaDogM_WriteChr,"%s",strPtr);
445 }
446 
447 
448 // Optional DisGIE, set to 1 to disable interrupts
449 // v1.4 -- provided by Imaginos
450 void eaDogM_WriteStringAtPos(int8 r, int8 c, char *strPtr, int1 DisGIE=0)
451 {
452  if (DisGIE) {
453  disable_interrupts(GLOBAL);
454  }
455 
457  printf(eaDogM_WriteChr,"%s",strPtr);
458 
459  if (DisGIE) {
460  enable_interrupts(GLOBAL);
461  }
462 }
463 
464 // Optional DisGIE, set to 1 to disable interrupts
465 // v1.4 -- provided by Imaginos
466 void eaDogM_WriteIntAtPos(int8 r, int8 c, int8 i, int1 DisGIE=0)
467 {
468  if (DisGIE) {
469  disable_interrupts(GLOBAL);
470  }
471 
473 
474  eaDogM_WriteChr(i/10+'0');
475  eaDogM_WriteChr(i%10+'0');
476 
477  if (DisGIE) {
478  enable_interrupts(GLOBAL);
479  }
480 }
481 
482 // this writes a byte to the internal CGRAM (v2.02)
483 // format for ndx: 00CCCRRR = CCC = character 0 to 7, RRR = row 0 to 7
484 void eaDogM_WriteByteToCGRAM(char ndx, char data)
485 {
486  unsigned int cmd;
487 
488  cmd = ndx & 0b00111111; // mask off upper to bits
489  cmd = cmd | EADOGM_CMD_CGRAM_ADDR; // set bit cmd bits
490 
491  eaDogM_WriteCommand(cmd);
492  eaDogM_WriteChr(data);
493 
494  // this is done to make sure we are back in data mode
495  eaDogM_SetPos(0,0);
496 }
497 
498 
499 #endif
#define GLOBAL
void eaDogM_WriteByteToCGRAM(char ndx, char data)
void eaDogM_SetPos(int8 r, int8 c)
#define EADOGM_INIT_CLEAR_DISPLAY
#define EADOGM_CMD_SELECT_R0
#define EADOGM_INIT_BIAS_SET
#define EADOGM_PIN_CSB
#define EADOGM_INIT_ENTRY_MODE
#define EADOGM_PIN_RS
#define EADOGM_INIT_FS1
void eaDogM_ClearRow(int8 r)
void eaDogM_WriteStringAtPos(int8 r, int8 c, char *strPtr, int1 DisGIE=0)
#define EADOGM_COLSPAN
#define eaDogM_outSPI(c)
#define EADOGM_CMD_DDRAM_ADDR
#define EADOGM_INIT_FS2
void eaDogM_DoubleHeight(int8 row)
#define EADOGM_CMD_CGRAM_ADDR
void eaDogM_WriteChr(char value)
void eaDogM_WriteIntAtPos(int8 r, int8 c, int8 i, int1 DisGIE=0)
#define EADOGM_CMD_SET_TABLE2
void eaDogM_WriteString(char *strPtr)
#define EADOGM_INIT_FOLLOWER_CONTROL
void eaDogM_Initialize(void)
#define EADOGM_SPI_DIV
#define EADOGM_CMD_SELECT_R1
#define EADOGM_INIT_POWER_CONTROL
#define EADOGM_INIT_CONTRAST_SET
void eaDogM_WriteCommand(int8 cmd)