OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_EFMG890F128_IAR/] [lcd/] [lcdcontroller.c] - Blame information for rev 595

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 595 jeremybenn
/**************************************************************************//**
2
 * @file
3
 * @brief LCD Controller driver
4
 * @author Energy Micro AS
5
 * @version 1.0.1
6
 ******************************************************************************
7
 * @section License
8
 * <b>(C) Copyright 2009 Energy Micro AS, http://www.energymicro.com</b>
9
 ******************************************************************************
10
 *
11
 * This source code is the property of Energy Micro AS. The source and compiled
12
 * code may only be used on Energy Micro "EFM32" microcontrollers.
13
 *
14
 * This copyright notice may not be removed from the source code nor changed.
15
 *
16
 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
17
 * obligation to support this Software. Energy Micro AS is providing the
18
 * Software "AS IS", with no express or implied warranties of any kind,
19
 * including, but not limited to, any implied warranties of merchantability
20
 * or fitness for any particular purpose or warranties against infringement
21
 * of any proprietary rights of a third party.
22
 *
23
 * Energy Micro AS will not be liable for any consequential, incidental, or
24
 * special damages, or any other relief, or for any claim by any third party,
25
 * arising from your use of this Software.
26
 *
27
 *****************************************************************************/
28
#include "FreeRTOS.h"
29
#include "task.h"
30
 
31
#include <stdio.h>
32
#include <string.h>
33
#include <stdlib.h>
34
#include "efm32.h"
35
#include "lcdcontroller.h"
36
#include "lcddisplay.h"
37
 
38
/** Counts every n'th frame */
39
int frameCounter = 0;
40
 
41
/**************************************************************************//**
42
 * @brief LCD Interrupt Handler, triggers on frame counter, every n'th frame
43
 *****************************************************************************/
44
void LCD_IRQHandler(void)
45
{
46
  LCD_TypeDef *lcd = LCD;
47
 
48
  /* clear interrupt */
49
  lcd->IFC = 0xFFFFFFFF;
50
  frameCounter++;
51
}
52
 
53
/**************************************************************************//**
54
 * @brief Enables a segment on the LCD display
55
 * @param lcd Pointer to LCD register block
56
 * @param com COM segment number
57
 * @param bitvalue Bit value for segment
58
 *****************************************************************************/
59
static void LCD_enableSegment(LCD_TypeDef * lcd, int com, int bitvalue)
60
{
61
  switch (com)
62
  {
63
  case 0:
64
    lcd->SEGD0L |= bitvalue;
65
    break;
66
  case 1:
67
    lcd->SEGD1L |= bitvalue;
68
    break;
69
  case 2:
70
    lcd->SEGD2L |= bitvalue;
71
    break;
72
  case 3:
73
    lcd->SEGD3L |= bitvalue;
74
    break;
75
  case 4:
76
    lcd->SEGD0H |= bitvalue;
77
    break;
78
  case 5:
79
    lcd->SEGD1H |= bitvalue;
80
    break;
81
  case 6:
82
    lcd->SEGD2H |= bitvalue;
83
    break;
84
  case 7:
85
    lcd->SEGD3H |= bitvalue;
86
    break;
87
  }
88
}
89
 
90
/**************************************************************************//**
91
 * @brief Disables a segment on the LCD Display
92
 * @param lcd Pointer to LCD register structure
93
 * @param com COM segment number
94
 * @param bitvalue Bit value for segment
95
 *****************************************************************************/
96
static void LCD_disableSegment(LCD_TypeDef * lcd, int com, int bitvalue)
97
{
98
  switch (com)
99
  {
100
  case 0:
101
    lcd->SEGD0L &= ~bitvalue;
102
    break;
103
  case 1:
104
    lcd->SEGD1L &= ~bitvalue;
105
    break;
106
  case 2:
107
    lcd->SEGD2L &= ~bitvalue;
108
    break;
109
  case 3:
110
    lcd->SEGD3L &= ~bitvalue;
111
    break;
112
  case 4:
113
    lcd->SEGD0H &= ~bitvalue;
114
    break;
115
  case 5:
116
    lcd->SEGD1H &= ~bitvalue;
117
    break;
118
  case 6:
119
    lcd->SEGD2H &= ~bitvalue;
120
    break;
121
  case 7:
122
    lcd->SEGD3H &= ~bitvalue;
123
    break;
124
  }
125
}
126
 
127
/**************************************************************************//**
128
 * @brief Write number on numeric part on LCD display
129
 * @param lcd Pointer to LCD control block
130
 * @param value Numeric value to put on display, in range -999 to +9999
131
 *****************************************************************************/
132
void LCD_Number(LCD_TypeDef *lcd, int value)
133
{
134
  int      num, i, com, bit, digit, div, neg;
135
  uint16_t bitpattern;
136
 
137
  /* Parameter consistancy check */
138
  if (value >= 9999)
139
  {
140
    value = 9999;
141
  }
142
  if (value <= -1000)
143
  {
144
    value = -999;
145
  }
146
  if (value < 0)
147
  {
148
    value = abs(value);
149
    neg   = 1;
150
  }
151
  else
152
  {
153
    neg = 0;
154
  }
155
  /* Extract useful digits */
156
  div = 1;
157
  for (digit = 0; digit < 4; digit++)
158
  {
159
    num = (value / div) % 10;
160
    if ((neg == 1) && (digit == 3)) num = 10;
161
    bitpattern = EM_Numbers[num];
162
    for (i = 0; i < 7; i++)
163
    {
164
      bit = EFMDisplay.Number[digit].bit[i];
165
      com = EFMDisplay.Number[digit].com[i];
166
      if (bitpattern & (1 << i))
167
      {
168
        LCD_enableSegment(lcd, com, 1 << bit);
169
      }
170
      else
171
      {
172
        LCD_disableSegment(lcd, com, 1 << bit);
173
      }
174
    }
175
    div = div * 10;
176
  }
177
}
178
 
179
/**************************************************************************//**
180
 * @brief Turn all segments on numeric display off
181
 * @param lcd Pointer to LCD register structure
182
 *****************************************************************************/
183
void LCD_NumberOff(LCD_TypeDef *lcd)
184
{
185
  int digit, i, bit, com;
186
 
187
  /* Turn off all segments */
188
  for (digit = 0; digit < 4; digit++)
189
  {
190
    for (i = 0; i < 7; i++)
191
    {
192
      bit = EFMDisplay.Number[digit].bit[i];
193
      com = EFMDisplay.Number[digit].com[i];
194
      LCD_disableSegment(lcd, com, 1 << bit);
195
    }
196
  }
197
  return;
198
}
199
 
200
 
201
/**************************************************************************//**
202
 * @brief Write text on LCD display
203
 * @param lcd Pointer to LCD register structure
204
 * @param string Text string to show on display
205
 *****************************************************************************/
206
void LCD_Write(LCD_TypeDef *lcd, char *string)
207
{
208
  int      data, length, index;
209
  uint16_t bitfield;
210
  uint32_t value;
211
  uint32_t com, bit;
212
  int      i;
213
 
214
  length = strlen(string);
215
  index  = 0;
216
  /* fill out all characters on display */
217
  for (index = 0; index < 7; index++)
218
  {
219
    if (index < length)
220
    {
221
      data = (int) *string;
222
    }
223
    else           /* padding with space */
224
    {
225
      data = 0x20; /* SPACE */
226
    }
227
    /* defined letters currently starts at "SPACE" - 0x20; */
228
    data     = data - 0x20;
229
    bitfield = EM_alphabet[data];
230
 
231
 
232
    for (i = 0; i < 14; i++)
233
    {
234
      bit   = EFMDisplay.Text[index].bit[i];
235
      com   = EFMDisplay.Text[index].com[i];
236
      value = (1 << bit);
237
 
238
      if (bitfield & (1 << i))
239
      {
240
        /* Turn on segment */
241
        LCD_enableSegment(lcd, com, value);
242
      }
243
      else
244
      {
245
        /* Turn off segment */
246
        LCD_disableSegment(lcd, com, value);
247
      }
248
    }
249
    string++;
250
  }
251
  while (lcd->SYNCBUSY) ;
252
}
253
 
254
/**************************************************************************//**
255
 * @brief LCD Disable all segments
256
 * @param lcd Pointer to LCD register block
257
 *****************************************************************************/
258
void LCD_AllOff(LCD_TypeDef *lcd)
259
{
260
  lcd->SEGD0L = 0x00000000;
261
  lcd->SEGD0H = 0x00000000;
262
  lcd->SEGD1L = 0x00000000;
263
  lcd->SEGD1H = 0x00000000;
264
  lcd->SEGD2L = 0x00000000;
265
  lcd->SEGD2H = 0x00000000;
266
  lcd->SEGD3L = 0x00000000;
267
  lcd->SEGD3H = 0x00000000;
268
  while (lcd->SYNCBUSY) ;
269
}
270
 
271
/**************************************************************************//**
272
 * @brief LCD Enable all segments
273
 * @param lcd Pointer to LCD register block
274
 *****************************************************************************/
275
void LCD_AllOn(LCD_TypeDef *lcd)
276
{
277
  lcd->SEGD0L = 0xffffffff;
278
  lcd->SEGD0H = 0xffffffff;
279
  lcd->SEGD1L = 0xffffffff;
280
  lcd->SEGD1H = 0xffffffff;
281
  lcd->SEGD2L = 0xffffffff;
282
  lcd->SEGD2H = 0xffffffff;
283
  lcd->SEGD3L = 0xffffffff;
284
  lcd->SEGD3H = 0xffffffff;
285
  while (lcd->SYNCBUSY) ;
286
}
287
 
288
/**************************************************************************//**
289
 * @brief LCD Light up or shut off Energy Mode indicator
290
 * @param lcd Pointer to LCD register block
291
 * @pararm em Energy Mode numer 0 to 4
292
 * @param on Zero is off, non-zero is on
293
 *****************************************************************************/
294
void LCD_EnergyMode(LCD_TypeDef *lcd, int em, int on)
295
{
296
  uint32_t com, bitvalue;
297
 
298
  com      = EFMDisplay.EMode.com[em];
299
  bitvalue = 1 << EFMDisplay.EMode.bit[em];
300
 
301
  if (on)
302
  {
303
    LCD_enableSegment(lcd, com, bitvalue);
304
  }
305
  else
306
  {
307
    LCD_disableSegment(lcd, com, bitvalue);
308
  }
309
}
310
 
311
/**************************************************************************//**
312
 * @brief LCD Light up or shut off Ring of Indicators
313
 * @param lcd Pointer to LCD register block
314
 * @param anum "Segment number" on "Ring", range 0 - 7
315
 * @param on Zero is off, non-zero is on
316
 *****************************************************************************/
317
void LCD_ARing(LCD_TypeDef *lcd, int anum, int on)
318
{
319
  uint32_t com, bitvalue;
320
 
321
  com      = EFMDisplay.ARing.com[anum];
322
  bitvalue = 1 << EFMDisplay.ARing.bit[anum];
323
 
324
  if (on)
325
  {
326
    LCD_enableSegment(lcd, com, bitvalue);
327
  }
328
  else
329
  {
330
    LCD_disableSegment(lcd, com, bitvalue);
331
  }
332
}
333
 
334
/**************************************************************************//**
335
 * @brief LCD Light up or shut off various symbols on LCD Display
336
 * @param lcd Pointer to LCD register block
337
 * @param s Which symbol to turn on or off
338
 * @param on Zero is off, non-zero is on
339
 *****************************************************************************/
340
void LCD_Symbol(LCD_TypeDef *lcd, lcdSymbol s, int on)
341
{
342
  int com, bit;
343
 
344
  switch (s)
345
  {
346
  case LCD_SYMBOL_GECKO:
347
    com = 3; bit = 8;
348
    break;
349
  case LCD_SYMBOL_ANT:
350
    com = 3; bit = 1;
351
    break;
352
  case LCD_SYMBOL_PAD0:
353
    com = 1; bit = 8;
354
    break;
355
  case LCD_SYMBOL_PAD1:
356
    com = 2; bit = 8;
357
    break;
358
  case LCD_SYMBOL_AM:
359
    com = 4; bit = 0;
360
    break;
361
  case LCD_SYMBOL_PM:
362
    com = 4; bit = 3;
363
    break;
364
  case LCD_SYMBOL_EFM32:
365
    com = 0; bit = 8;
366
    break;
367
  case LCD_SYMBOL_MINUS:
368
    com = 0; bit = 9;
369
    break;
370
  case LCD_SYMBOL_COL3:
371
    com = 0; bit = 16;
372
    break;
373
  case LCD_SYMBOL_COL5:
374
    com = 0; bit = 24;
375
    break;
376
  case LCD_SYMBOL_COL10:
377
    com = 4; bit = 7;
378
    break;
379
  case LCD_SYMBOL_DP2:
380
    com = 4; bit = 2;
381
    break;
382
  case LCD_SYMBOL_DP3:
383
    com = 5; bit = 2;
384
    break;
385
  case LCD_SYMBOL_DP4:
386
    com = 6; bit = 2;
387
    break;
388
  case LCD_SYMBOL_DP5:
389
    com = 7; bit = 2;
390
    break;
391
  case LCD_SYMBOL_DP6:
392
    com = 0; bit = 21;
393
    break;
394
  case LCD_SYMBOL_DP10:
395
    com = 4; bit = 5;
396
    break;
397
  }
398
  if (on)
399
  {
400
    LCD_enableSegment(lcd, com, 1 << bit);
401
  }
402
  else
403
  {
404
    LCD_disableSegment(lcd, com, 1 << bit);
405
  }
406
}
407
 
408
/**************************************************************************//**
409
 * @brief LCD Light up or shut off Battery Indicator
410
 * @param lcd Pointer to LCD register block
411
 * @param batteryLevel Battery Level, 0 to 4 (0 turns all off)
412
 *****************************************************************************/
413
void LCD_Battery(LCD_TypeDef *lcd, int batteryLevel)
414
{
415
  uint32_t com, bitvalue;
416
  int      i, on;
417
 
418
  for (i = 0; i < 4; i++)
419
  {
420
    if (i < batteryLevel)
421
    {
422
      on = 1;
423
    }
424
    else
425
    {
426
      on = 0;
427
    }
428
    com      = EFMDisplay.Battery.com[i];
429
    bitvalue = 1 << EFMDisplay.Battery.bit[i];
430
 
431
    if (on)
432
    {
433
      LCD_enableSegment(lcd, com, bitvalue);
434
    }
435
    else
436
    {
437
      LCD_disableSegment(lcd, com, bitvalue);
438
    }
439
  }
440
}
441
 
442
/**************************************************************************//**
443
 * @brief LCD Initialization routine for EFM32 DVK display
444
 * @param lcd Pointer to LCD register block
445
 *****************************************************************************/
446
void LCD_Init(LCD_TypeDef *lcd)
447
{
448
  CMU_TypeDef *cmu = CMU;
449
 
450
  /* Enable LFXO oscillator */
451
  cmu->OSCENCMD |= CMU_OSCENCMD_LFXOEN;
452
  while (!(cmu->STATUS & CMU_STATUS_LFXORDY)) ;
453
 
454
  /* Enable LCD clock in CMU */
455
  cmu->LFACLKEN0 |= CMU_LFACLKEN0_LCD;
456
 
457
  /* Select LFXO for LCD */
458
  cmu->LFCLKSEL = CMU_LFCLKSEL_LFA_LFXO | CMU_LFCLKSEL_LFB_LFXO;
459
 
460
  /* LCD Controller Prescaler (divide by 1) */
461
  /* CLKlcd = 0.25 kHz */
462
  cmu->LFAPRESC0 &= ~_CMU_LFAPRESC0_LCD_MASK;
463
  cmu->LFAPRESC0 |= _CMU_LFAPRESC0_LCD_DIV128 << _CMU_LFAPRESC0_LCD_SHIFT;
464
 
465
  /* Set up interrupt handler */
466
  lcd->IEN = 0;
467
  while (lcd->SYNCBUSY) ;
468
 
469
  /* Clear pending interrupts */
470
  lcd->IFC = ~0;
471
  /* Enable interrupt */
472
  NVIC_EnableIRQ(LCD_IRQn);
473
  lcd->IEN = LCD_IEN_FC;
474
 
475
  /* Frame rate is 32Hz, 0.25Khz LFCLK128, QUADRUPLEX mode, FDIV=0 */
476
  lcd->DISPCTRL = LCD_DISPCTRL_MUX_QUADRUPLEX |
477
                  LCD_DISPCTRL_BIAS_ONETHIRD |
478
                  LCD_DISPCTRL_WAVE_LOWPOWER |
479
                  LCD_DISPCTRL_CONLEV_MAX |
480
                  LCD_DISPCTRL_VLCDSEL_VDD |
481
                  LCD_DISPCTRL_VBLEV_3V00;
482
 
483
  /* No voltage boost, framerate 32Hz */
484
  cmu->LCDCTRL = 0;
485
 
486
  /* Turn all segments off */
487
  LCD_AllOff(lcd);
488
 
489
  /* Enable all segment registers */
490
  lcd->SEGEN = 0x000003FF;
491
  lcd->CTRL  = LCD_CTRL_EN | LCD_CTRL_UDCTRL_FRAMESTART;
492
  while (lcd->SYNCBUSY) ;
493
 
494
  /* Configure LCD to give a frame counter interrupt every 8th frame. */
495
  lcd->BACTRL = LCD_BACTRL_FCEN | (7 << _LCD_BACTRL_FCTOP_SHIFT) | (0 << _LCD_BACTRL_FCPRESC_SHIFT);
496
  while (lcd->SYNCBUSY) ;
497
  lcd->IFC = LCD_IFC_FC;
498
  lcd->IEN = LCD_IEN_FC;
499
}
500
 
501
 
502
/**************************************************************************//**
503
 * @brief Disables LCD controller
504
 * @param lcd Pointer to LCD register block
505
 *****************************************************************************/
506
void LCD_Disable(LCD_TypeDef *lcd)
507
{
508
  CMU_TypeDef *cmu = CMU;
509
 
510
  /* Turn off interrupts */
511
  lcd->IEN = 0x00000000;
512
  lcd->IFC = LCD_IFC_FC;
513
  NVIC_DisableIRQ(LCD_IRQn);
514
  /* Disable LCD */
515
  lcd->CTRL = 0;
516
  /* Turn off LCD clock */
517
  cmu->LFACLKEN0 &= ~(CMU_LFACLKEN0_LCD);
518
  /* Turn off voltage boost if enabled */
519
  cmu->LCDCTRL = 0;
520
}
521
 
522
/**************************************************************************//**
523
 * @brief LCD scrolls a text over the display, sort of "polled printf"
524
 * @param lcd Pointer to LCD register block
525
 *****************************************************************************/
526
void LCD_ScrollText(LCD_TypeDef *lcd, char *scrolltext)
527
{
528
  int  i, len;
529
  char buffer[8];
530
 
531
  buffer[7] = 0x00;
532
  len       = strlen(scrolltext);
533
  if (len < 7) return;
534
  for (i = 0; i < (len - 7); i++)
535
  {
536
    memcpy(buffer, scrolltext + i, 7);
537
    LCD_Write(lcd, buffer);
538
    vTaskDelay(100/portTICK_RATE_MS);
539
  }
540
}
541
 
542
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.