source: rtems/c/src/libchip/display/disp_hcms29xx.c @ 06a36cd1

4.11
Last change on this file since 06a36cd1 was 06a36cd1, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 7, 2011 at 10:15:25 PM

2011-07-07 Joel Sherrill <joel.sherrill@…>

  • libchip/display/disp_hcms29xx.c, libchip/flash/am29lv160.c, libchip/i2c/i2c-2b-eeprom.c, libchip/i2c/i2c-ds1621.c, libchip/i2c/spi-flash-m25p40.c, libchip/i2c/spi-fram-fm25l256.c, libchip/i2c/spi-memdrv.c, libchip/rtc/ds1375.c: Eliminate use of GNU old-style field designator extension as recommended by clang.
  • Property mode set to 100644
File size: 32.7 KB
Line 
1/*===============================================================*\
2| Project: display driver for HCMS29xx                            |
3+-----------------------------------------------------------------+
4| File: disp_hcms29xx.c                                           |
5+-----------------------------------------------------------------+
6|                    Copyright (c) 2008                           |
7|                    Embedded Brains GmbH                         |
8|                    Obere Lagerstr. 30                           |
9|                    D-82178 Puchheim                             |
10|                    Germany                                      |
11|                    rtems@embedded-brains.de                     |
12+-----------------------------------------------------------------+
13| The license and distribution terms for this file may be         |
14| found in the file LICENSE in this distribution or at            |
15|                                                                 |
16| http://www.rtems.com/license/LICENSE.                           |
17|                                                                 |
18+-----------------------------------------------------------------+
19| this file contains the SPI based driver for a HCMS29xx 4 digit  |
20| alphanumeric LED display                                        |
21+-----------------------------------------------------------------+
22|  $Id$
23\*===============================================================*/
24
25#include <string.h>
26#include <stdlib.h>
27
28#ifndef ARRAY_COUNT
29#define ARRAY_COUNT(a) (sizeof(a)/sizeof(a[0]))
30#endif /* ARRAY_COUNT */
31
32#include <rtems.h>
33#include <rtems/libio.h>
34#include <bsp.h>
35#include <rtems/libi2c.h>
36#include <libchip/disp_hcms29xx.h>
37#include "font_hcms29xx.h"
38#define FONT_BASE font_hcms29xx_base
39
40
41#define DISP_HCMS29XX_DIGIT_CNT (4)
42#define DISP_HCMS29XX_SEMA_NAME      rtems_build_name('D','4','I','Q')
43#define DISP_HCMS29XX_TRNS_SEMA_NAME rtems_build_name('D','4','T','R')
44#define DISP_HCMS29XX_TIMER_NAME     rtems_build_name('D','4','T','M')
45#define DISP_HCMS29XX_TASK_NAME      rtems_build_name('D','4','T','A')
46
47#define DISP_HCMS29XX_EVENT_TIMER  RTEMS_EVENT_1
48#define DISP_HCMS29XX_EVENT_NEWSTR RTEMS_EVENT_2
49
50
51static disp_font_t disp_hcms29xx_font_normal;
52static disp_font_t disp_hcms29xx_font_rotate;
53const rtems_libi2c_tfr_mode_t spi_disphcms29xx_tfr_mode = {
54  .baudrate = 1000000,
55  .bits_per_char = 8,
56  .lsb_first = true,
57  .clock_inv = true,
58  .clock_phs = true,
59  .idle_char = 0
60};
61
62static disp_hcms29xx_drv_t disp_hcms29xx_drv_tbl;
63
64/*=========================================
65 * font management functions
66 */
67
68/*=========================================================================*\
69| Function:                                                                 |
70\*-------------------------------------------------------------------------*/
71static rtems_status_code disp_hcms29xx_font_struct_size
72  (
73/*-------------------------------------------------------------------------*\
74| Purpose:                                                                  |
75|   compute size of font data structure tree                                |
76+---------------------------------------------------------------------------+
77| Input Parameters:                                                         |
78\*-------------------------------------------------------------------------*/
79  disp_font_t            src,           /* source font                     */
80  size_t                *dst_size       /* destination: size of font struct*/
81)
82/*-------------------------------------------------------------------------*\
83| Return Value:                                                             |
84|    rtems_status_code                                                      |
85\*=========================================================================*/
86{
87
88  rtems_status_code rc = RTEMS_SUCCESSFUL;
89  size_t font_size = 0;
90  size_t glyph_idx;
91  /*
92   * check parameters
93   */
94  if ((rc == RTEMS_SUCCESSFUL) &&
95      (src == NULL)) {
96    rc = RTEMS_INVALID_ADDRESS;
97  }
98  if (rc == RTEMS_SUCCESSFUL) {
99    font_size =
100      sizeof(*src);                      /* font_base structure       */
101  }
102  glyph_idx = 0;
103  while ((rc == RTEMS_SUCCESSFUL) &&
104         (glyph_idx < (sizeof(src->latin1)/sizeof(src->latin1[0])))) {
105    if (src->latin1[glyph_idx] != NULL) {
106      font_size += sizeof(*(src->latin1[glyph_idx]))
107        + (size_t) src->latin1[glyph_idx]->bb.w;
108    }
109    glyph_idx++;
110  }
111  *dst_size = font_size;
112
113  return rc;
114}
115
116/*=========================================================================*\
117| Function:                                                                 |
118\*-------------------------------------------------------------------------*/
119static inline unsigned char disp_hcms29xx_bitswap
120  (
121/*-------------------------------------------------------------------------*\
122| Purpose:                                                                  |
123|   swap data bits in byte (7<->0 , 6<->1 etc)                              |
124+---------------------------------------------------------------------------+
125| Input Parameters:                                                         |
126\*-------------------------------------------------------------------------*/
127  unsigned char byte
128)
129/*-------------------------------------------------------------------------*\
130| Return Value:                                                             |
131|    rtems_status_code                                                      |
132\*=========================================================================*/
133{
134  unsigned char result = 0;
135  int smsk,dmsk;
136  for (smsk =  0x01,dmsk=0x80;
137       smsk < 0x100;
138       smsk<<=1   ,dmsk>>=1) {
139    if ((byte & smsk) != 0) {
140      result |= (unsigned char) dmsk;
141    }
142  }
143  return result;
144}
145
146/*=========================================================================*\
147| Function:                                                                 |
148\*-------------------------------------------------------------------------*/
149static rtems_status_code disp_hcms29xx_copy_font
150  (
151/*-------------------------------------------------------------------------*\
152| Purpose:                                                                  |
153|   copy font data from source to dest font structure                       |
154+---------------------------------------------------------------------------+
155| Input Parameters:                                                         |
156\*-------------------------------------------------------------------------*/
157  disp_font_t src,                      /* source font                     */
158  struct disp_font_base *dst,           /* ptr to destination font         */
159  int shift_cnt,                        /* shift count for font            */
160  bool do_rotate                        /* rotate font, if true            */
161)
162/*-------------------------------------------------------------------------*\
163| Return Value:                                                             |
164|    rtems_status_code                                                      |
165\*=========================================================================*/
166{
167
168  rtems_status_code rc = RTEMS_SUCCESSFUL;
169  char *alloc_next = (char *)dst;
170  size_t glyph_idx = 0;
171  int glyph_size;
172  unsigned char byte;
173  int bcnt;
174
175  /*
176   * check parameters
177   */
178  if ((rc == RTEMS_SUCCESSFUL) &&
179      ((src == NULL) ||
180       (dst == NULL))) {
181    rc = RTEMS_INVALID_ADDRESS;
182  }
183  /*
184   * copy font_base structure
185   */
186  if (rc == RTEMS_SUCCESSFUL) {
187    *dst = *src;
188    alloc_next += sizeof(*dst);
189  }
190  /*
191   * for all glyphs: assign own glyph memory
192   */
193  glyph_idx = 0;
194  while ((rc == RTEMS_SUCCESSFUL) &&
195         glyph_idx < (sizeof(src->latin1)/sizeof(src->latin1[0]))) {
196    if (src->latin1[glyph_idx] != NULL) {
197      /*
198       * allocate space for glyph
199       */
200      dst->latin1[glyph_idx] = (struct disp_font_glyph *)alloc_next;
201      alloc_next += sizeof(*(dst->latin1[glyph_idx]));
202      /*
203       * copy source values.
204       * Note: bitmap will be reassigned later
205       */
206      *(struct disp_font_glyph *)(dst->latin1[glyph_idx]) =
207        *(src->latin1[glyph_idx]);
208    }
209    else {
210      dst->latin1[glyph_idx] = NULL;
211    }
212    glyph_idx++;
213  }
214
215  /*
216   * for all glyphs: reassign bitmap
217   */
218  glyph_idx = 0;
219  while ((rc == RTEMS_SUCCESSFUL) &&
220         glyph_idx < (sizeof(src->latin1)/sizeof(src->latin1[0]))) {
221    if (src->latin1[glyph_idx] != NULL) {
222      glyph_size = src->latin1[glyph_idx]->bb.w;
223      /*
224       * allocate space for glyph_bitmap
225       */
226      dst->latin1[glyph_idx]->bitmap = (const unsigned char *) alloc_next;
227      alloc_next += glyph_size;
228      /*
229       * copy/transform bitmap
230       */
231      for (bcnt = 0;bcnt < glyph_size;bcnt++) {
232        if (do_rotate) {
233          byte = src->latin1[glyph_idx]->bitmap[glyph_size - 1 - bcnt];
234          byte = disp_hcms29xx_bitswap(byte);
235        }
236        else {
237          byte = src->latin1[glyph_idx]->bitmap[bcnt];
238        }
239        if (shift_cnt < 0) {
240          byte = byte >> shift_cnt;
241        }
242        else if (shift_cnt > 0) {
243          byte = byte >> shift_cnt;
244        }
245        ((unsigned char *)(dst->latin1[glyph_idx]->bitmap))[bcnt] = byte;
246      }
247    }
248    glyph_idx++;
249  }
250  return rc;
251}
252
253/*=========================================================================*\
254| Function:                                                                 |
255\*-------------------------------------------------------------------------*/
256static rtems_status_code disp_hcms29xx_alloc_copy_font
257  (
258/*-------------------------------------------------------------------------*\
259| Purpose:                                                                  |
260|   copy font data from source to dest font structure, alloc all data       |
261+---------------------------------------------------------------------------+
262| Input Parameters:                                                         |
263\*-------------------------------------------------------------------------*/
264  const disp_font_t src,                /* source font                     */
265  disp_font_t *dst,                     /* ptr to destination font         */
266  int shift_cnt,                        /* shift count for font            */
267  bool do_rotate                        /* rotate font, if true            */
268)
269/*-------------------------------------------------------------------------*\
270| Return Value:                                                             |
271|    rtems_status_code                                                      |
272\*=========================================================================*/
273{
274
275  rtems_status_code rc = RTEMS_SUCCESSFUL;
276  size_t src_size = 0;
277  /*
278   * check parameters
279   */
280  if ((rc == RTEMS_SUCCESSFUL) &&
281      ((src == NULL)
282       || (dst == NULL))) {
283    rc = RTEMS_INVALID_ADDRESS;
284  }
285  /*
286   * determine size of source data
287   */
288  if (rc == RTEMS_SUCCESSFUL) {
289    rc = disp_hcms29xx_font_struct_size(src,&src_size);
290  }
291  /*
292   * allocate proper data area
293   */
294  if (rc == RTEMS_SUCCESSFUL) {
295    *dst = malloc(src_size);
296    if (*dst == NULL) {
297      rc = RTEMS_UNSATISFIED;
298    }
299  }
300  /*
301   * scan through source data, copy to dest
302   */
303  if (rc == RTEMS_SUCCESSFUL) {
304    rc = disp_hcms29xx_copy_font(src,*dst,shift_cnt,do_rotate);
305  }
306  return rc;
307}
308
309/*=========================================
310 * SPI communication functions
311 */
312
313/*=========================================================================*\
314| Function:                                                                 |
315\*-------------------------------------------------------------------------*/
316static rtems_status_code disp_hcms29xx_send_to_display
317  (
318/*-------------------------------------------------------------------------*\
319| Purpose:                                                                  |
320|   request access semaphore to SPI, prepare buffer descriptors, start      |
321|   transfer via SPI to display                                             |
322+---------------------------------------------------------------------------+
323| Input Parameters:                                                         |
324\*-------------------------------------------------------------------------*/
325   disp_hcms29xx_drv_t *softc_ptr,
326   const volatile char *disp_buffer /* start of chars to display (4 chars or 'til \0)*/
327)
328/*-------------------------------------------------------------------------*\
329| Return Value:                                                             |
330|    rtems_status_code                                                      |
331\*=========================================================================*/
332{
333  rtems_status_code rc = RTEMS_SUCCESSFUL;
334  bool char_avail;
335  const struct disp_font_glyph *glyph_ptr;
336  disp_font_t curr_font;
337  int i,digit,ret_cnt;
338  unsigned char c;
339
340  /*
341   * select device, set transfer mode, address device
342   */
343  if (rc == RTEMS_SUCCESSFUL) {
344    rc = rtems_libi2c_send_start(softc_ptr->disp_param.minor);
345  }
346  /*
347   * set transfer mode
348   */
349  if (rc == RTEMS_SUCCESSFUL) {
350    rc = -rtems_libi2c_ioctl(softc_ptr->disp_param.minor,
351                             RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
352                             &spi_disphcms29xx_tfr_mode);
353  }
354
355  /*
356   * address device
357   */
358  if (rc == RTEMS_SUCCESSFUL) {
359    rc = rtems_libi2c_send_addr(softc_ptr->disp_param.minor,true);
360  }
361
362  /*
363   * send data
364   */
365  if (rc == RTEMS_SUCCESSFUL) {
366    curr_font =
367      softc_ptr->disp_param.rotate
368      ? disp_hcms29xx_font_rotate
369      : disp_hcms29xx_font_normal;
370
371    char_avail = true;
372    /*
373     * FIXME: for rotated display, write last character first...
374     * maybe we should copy everything to a common buffer and use
375     * ONE SPI transfer?
376     */
377    for (i = 0;
378         ((rc == RTEMS_SUCCESSFUL) &&
379          (i < DISP_HCMS29XX_DIGIT_CNT));
380          i++) {
381      /* test for end of string... */
382      c = disp_buffer[i]; /* perform consistent read of disp_buffer */
383      if (char_avail && (c == '\0')) {
384        char_avail = false;
385      }
386      glyph_ptr = (char_avail
387                   ? curr_font->latin1[c]
388                   : NULL);
389      if (glyph_ptr == NULL) {
390        glyph_ptr = curr_font->latin1[' '];
391      }
392
393      digit = (softc_ptr->disp_param.rotate
394               ? DISP_HCMS29XX_DIGIT_CNT-1-i
395               : i);
396      /*
397       * send 5 bytes from (char *)glyph_ptr->bitmap to SPI
398       */
399      if (rc == RTEMS_SUCCESSFUL) {
400        ret_cnt = rtems_libi2c_write_bytes(softc_ptr->disp_param.minor,
401                                           glyph_ptr->bitmap,5);
402        if (ret_cnt < 0) {
403          rc = -ret_cnt;
404        }
405      }
406    }
407  }
408  /*
409   * finish transfer
410   */
411  if (rc == RTEMS_SUCCESSFUL) {
412    rc = rtems_libi2c_send_stop(softc_ptr->disp_param.minor);
413  }
414
415  return rc;
416}
417
418/*=========================================================================*\
419| Function:                                                                 |
420\*-------------------------------------------------------------------------*/
421static rtems_status_code disp_hcms29xx_send_to_control
422  (
423/*-------------------------------------------------------------------------*\
424| Purpose:                                                                  |
425|   request access semaphore to SPI, prepare buffer descriptors, start      |
426|   transfer via SPI to display                                             |
427+---------------------------------------------------------------------------+
428| Input Parameters:                                                         |
429\*-------------------------------------------------------------------------*/
430   disp_hcms29xx_drv_t *softc_ptr,
431   int pwm,   /* value for pwm of LEDs, 0..15 */
432   int peak,  /* value for peak current for LEDs, 0..3 */
433   int sleep, /* value to make display "sleep" (0..1 */
434   int div,   /* divider for external osc input, unused here */
435   int chain  /* mode to drive other displays, unused here */
436)
437/*-------------------------------------------------------------------------*\
438| Return Value:                                                             |
439|    rtems_status_code                                                      |
440\*=========================================================================*/
441{
442  rtems_status_code rc = RTEMS_SUCCESSFUL;
443  int run, ret_cnt;
444  uint8_t ctrl_buffer;
445
446  /* two accesses, control word 0 and 1 */
447  for (run = 0;
448       ((rc == RTEMS_SUCCESSFUL) && (run <= 1));
449       run++) {
450    if (rc == RTEMS_SUCCESSFUL) {
451      if (run == 0) {
452        ctrl_buffer =
453          (0              << 7) |
454          ((sleep & 0x01) << 6) |
455          ((peak  & 0x03) << 4) |
456          ((pwm & 0x0f)   << 0);
457      }
458      else {
459        ctrl_buffer =
460          (1              << 7) |
461          ((div   & 0x01) << 1) |
462          ((chain & 0x01) << 0);
463      }
464      /*
465       * select device, set transfer mode, address device
466       */
467      if (rc == RTEMS_SUCCESSFUL) {
468        rc = rtems_libi2c_send_start(softc_ptr->disp_param.minor);
469      }
470      /*
471       * set transfer mode
472       */
473      if (rc == RTEMS_SUCCESSFUL) {
474        rc = -rtems_libi2c_ioctl(softc_ptr->disp_param.minor,
475                                 RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
476                                 &spi_disphcms29xx_tfr_mode);
477      }
478
479      /*
480       * address device
481       */
482      if (rc == RTEMS_SUCCESSFUL) {
483        rc = rtems_libi2c_send_addr(softc_ptr->disp_param.minor,true);
484      }
485
486      /*
487       * send 1 byte from ctrl_buffer
488       */
489      if (rc == RTEMS_SUCCESSFUL) {
490        ret_cnt = rtems_libi2c_write_bytes(softc_ptr->disp_param.minor,
491                                           &ctrl_buffer,1);
492        if (ret_cnt < 0) {
493          rc = -ret_cnt;
494        }
495      }
496    }
497  } /* next run ... */
498
499  /*
500   * finish transfer
501   */
502  if (rc == RTEMS_SUCCESSFUL) {
503    rc = rtems_libi2c_send_stop(softc_ptr->disp_param.minor);
504  }
505
506  return rc;
507}
508
509/*=========================================================================*\
510| Function:                                                                 |
511\*-------------------------------------------------------------------------*/
512static rtems_timer_service_routine disp_hcms29xx_timer_sr
513/*-------------------------------------------------------------------------*\
514| Purpose:                                                                  |
515|   this task updates the string in the display                             |
516+---------------------------------------------------------------------------+
517| Input Parameters:                                                         |
518\*-------------------------------------------------------------------------*/
519(
520 rtems_id id, /* ID of timer, not used  */
521 void * arg   /* calling arg: softc_ptr */
522)
523/*-------------------------------------------------------------------------*\
524| Return Value:                                                             |
525|    <none used>                                                            |
526\*=========================================================================*/
527{
528  rtems_status_code rc = RTEMS_SUCCESSFUL;
529  disp_hcms29xx_drv_t *softc_ptr = arg;
530
531
532  if (rc == RTEMS_SUCCESSFUL) {
533    rc = rtems_event_send(softc_ptr->disp_param.task_id,
534                          DISP_HCMS29XX_EVENT_TIMER);
535  }
536}
537
538/*=========================================================================*\
539| Function:                                                                 |
540\*-------------------------------------------------------------------------*/
541static rtems_task disp_hcms29xx_update_task
542  (
543/*-------------------------------------------------------------------------*\
544| Purpose:                                                                  |
545|   this task updates the string in the display                             |
546+---------------------------------------------------------------------------+
547| Input Parameters:                                                         |
548\*-------------------------------------------------------------------------*/
549   rtems_task_argument argument
550)
551/*-------------------------------------------------------------------------*\
552| Return Value:                                                             |
553|    <never exits>                                                          |
554\*=========================================================================*/
555{
556  rtems_event_set  my_events;
557  rtems_status_code rc = RTEMS_SUCCESSFUL;
558  int disp_offset = 0;
559  rtems_id disp_hcms29xx_timer_id;
560  disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
561
562  /*
563   * initialize display:
564   */
565  /*
566   * set control attributes for display
567   * maximum brightness...
568   */
569  if (rc == RTEMS_SUCCESSFUL) {
570    rc = disp_hcms29xx_send_to_control(softc_ptr,
571                                       14,3,1,0,0);/* pwm/peak/nosleep/div/chain */
572  }
573
574  /*
575   * set display to blank
576   */
577  if (rc == RTEMS_SUCCESSFUL) {
578    rc = disp_hcms29xx_send_to_display(softc_ptr,
579                                       "");
580  }
581
582  /*
583   * create timer for scrolling
584   */
585  if (rc == RTEMS_SUCCESSFUL) {
586    rc = rtems_timer_create(DISP_HCMS29XX_TIMER_NAME,
587                            &disp_hcms29xx_timer_id);
588  }
589
590  while (rc == RTEMS_SUCCESSFUL) {
591    /*
592     * wait for any event
593     */
594    rc = rtems_event_receive(DISP_HCMS29XX_EVENT_NEWSTR |
595                             DISP_HCMS29XX_EVENT_TIMER ,
596                             RTEMS_WAIT | RTEMS_EVENT_ANY,
597                             RTEMS_NO_TIMEOUT,
598                             &my_events);
599    if (my_events & DISP_HCMS29XX_EVENT_NEWSTR) {
600      /*
601       * fetch new string consistently into local buffer
602       */
603      if (rc == RTEMS_SUCCESSFUL) {
604        rc = rtems_semaphore_obtain(softc_ptr->disp_param.trns_sema_id,
605                                    RTEMS_WAIT,RTEMS_NO_TIMEOUT);
606      }
607      if (rc == RTEMS_SUCCESSFUL) {
608        strncpy(softc_ptr->disp_param.disp_buffer,
609                softc_ptr->disp_param.trns_buffer,
610                sizeof(softc_ptr->disp_param.disp_buffer));
611        softc_ptr->disp_param.disp_buffer[sizeof(softc_ptr->disp_param.disp_buffer)-1] = '\0';
612        softc_ptr->disp_param.disp_buf_cnt =
613          (int) strlen(softc_ptr->disp_param.disp_buffer);
614      }
615      if (rc == RTEMS_SUCCESSFUL) {
616        rc = rtems_semaphore_release(softc_ptr->disp_param.trns_sema_id);
617      }
618      /*
619       * set initial offset to negative value
620       * to make string static for some ticks
621       */
622      disp_offset = -4;
623    }
624    if (my_events & DISP_HCMS29XX_EVENT_TIMER) {
625      /*
626       * increase disp_offset, if possible, otherwise reset it
627       */
628      if ((disp_offset < 0) ||
629          (disp_offset < softc_ptr->disp_param.disp_buf_cnt-
630           DISP_HCMS29XX_DIGIT_CNT/2)) {
631        disp_offset++;
632      }
633      else {
634        disp_offset = -4;
635      }
636    }
637    /*
638     * display string, starting from disp_offset
639     */
640    if (disp_offset < 0) {
641      rc = disp_hcms29xx_send_to_display(softc_ptr,
642                                         softc_ptr->disp_param.disp_buffer);
643    }
644    else if (disp_offset
645             < (softc_ptr->disp_param.disp_buf_cnt - DISP_HCMS29XX_DIGIT_CNT)) {
646      rc = disp_hcms29xx_send_to_display(softc_ptr,
647                                         softc_ptr->disp_param.disp_buffer+disp_offset);
648    }
649    else {
650      rc = disp_hcms29xx_send_to_display(softc_ptr,
651                                         softc_ptr->disp_param.disp_buffer
652                                         + softc_ptr->disp_param.disp_buf_cnt
653                                         - DISP_HCMS29XX_DIGIT_CNT);
654    }
655    /*
656     * activate timer, if needed
657     */
658    if (rc == RTEMS_SUCCESSFUL) {
659      if (softc_ptr->disp_param.disp_buf_cnt > DISP_HCMS29XX_DIGIT_CNT) {
660        rc = rtems_timer_fire_after(disp_hcms29xx_timer_id,
661                                    50,
662                                    disp_hcms29xx_timer_sr,
663                                    NULL);
664      }
665      else {
666        rc = rtems_timer_cancel(disp_hcms29xx_timer_id);
667      }
668    }
669  }
670  /*
671   * FIXME: display task is dead...
672   */
673}
674
675/*=========================================================================*\
676| Function:                                                                 |
677\*-------------------------------------------------------------------------*/
678static rtems_status_code disp_hcms29xx_update
679  (
680/*-------------------------------------------------------------------------*\
681| Purpose:                                                                  |
682|   move given string to display task                                       |
683+---------------------------------------------------------------------------+
684| Input Parameters:                                                         |
685\*-------------------------------------------------------------------------*/
686   disp_hcms29xx_drv_t *softc_ptr,
687   const char *src
688)
689/*-------------------------------------------------------------------------*\
690| Return Value:                                                             |
691|    rtems_status_code                                                      |
692\*=========================================================================*/
693{
694  rtems_status_code rc = RTEMS_SUCCESSFUL;
695
696  /*
697   * obtain trns semaphore
698   */
699  if (rc == RTEMS_SUCCESSFUL) {
700    rc = rtems_semaphore_obtain(softc_ptr->disp_param.trns_sema_id,
701                                RTEMS_WAIT,RTEMS_NO_TIMEOUT);
702  }
703  /*
704   * copy string...
705   */
706  strncpy(softc_ptr->disp_param.trns_buffer,src,
707          sizeof(softc_ptr->disp_param.trns_buffer));
708  softc_ptr->disp_param.trns_buffer[sizeof(softc_ptr->disp_param.trns_buffer)-1] = '\0';
709
710  /*
711   * release trns semaphore
712   */
713  if (rc == RTEMS_SUCCESSFUL) {
714    rc = rtems_semaphore_release(softc_ptr->disp_param.trns_sema_id);
715  }
716
717  /*
718   * send event to task
719   */
720  if (rc == RTEMS_SUCCESSFUL) {
721    rc = rtems_event_send(softc_ptr->disp_param.task_id,
722                          DISP_HCMS29XX_EVENT_NEWSTR);
723  }
724
725  return rc;
726}
727
728/*=========================================================================*\
729| Function:                                                                 |
730\*-------------------------------------------------------------------------*/
731rtems_device_driver disp_hcms29xx_dev_initialize
732  (
733/*-------------------------------------------------------------------------*\
734| Purpose:                                                                  |
735|   prepare the display device driver to accept write calls                 |
736|   register device with its name                                           |
737+---------------------------------------------------------------------------+
738| Input Parameters:                                                         |
739\*-------------------------------------------------------------------------*/
740  rtems_device_major_number  major,
741  rtems_device_minor_number  minor,
742  void                      *arg
743)
744/*-------------------------------------------------------------------------*\
745| Return Value:                                                             |
746|    rtems_status_code                                                      |
747\*=========================================================================*/
748/*
749 * Initialize and register the device
750 */
751{
752  rtems_status_code rc = RTEMS_SUCCESSFUL;
753  disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
754
755  /*
756   * initialize font management
757   * FIXME: check, that default glyph exists
758   * FIXME: check font size to be 5x7
759   */
760  /*
761   * translate font according to direction/baseline
762   */
763  if (rc == RTEMS_SUCCESSFUL) {
764    rc = disp_hcms29xx_alloc_copy_font(
765                               &FONT_BASE,
766                               &disp_hcms29xx_font_normal,
767                               FONT_BASE.descent, /* shift to visibility... */
768                               FALSE); /* do not rotate */
769  }
770  /* FIXME: translate font for rotation */
771  if (rc == RTEMS_SUCCESSFUL) {
772    rc = disp_hcms29xx_alloc_copy_font(&FONT_BASE,
773                               &disp_hcms29xx_font_rotate,
774                               0, /* do not shift */
775                               true); /* rotate font */
776  }
777  /*
778   * create the trns_buffer semaphore
779   */
780  if (rc == RTEMS_SUCCESSFUL) {
781    rc = rtems_semaphore_create (DISP_HCMS29XX_TRNS_SEMA_NAME,1,
782                                     RTEMS_PRIORITY
783                                     |RTEMS_BINARY_SEMAPHORE
784                                     |RTEMS_INHERIT_PRIORITY
785                                     |RTEMS_NO_PRIORITY_CEILING
786                                     |RTEMS_LOCAL,
787                                     0,
788                                     &softc_ptr->disp_param.trns_sema_id);
789  }
790
791  /*
792   * create and start display task
793   */
794  if (rc == RTEMS_SUCCESSFUL) {
795    rc = rtems_task_create(DISP_HCMS29XX_TASK_NAME,
796                           20,
797                           RTEMS_MINIMUM_STACK_SIZE,
798                           RTEMS_INTERRUPT_LEVEL(0) | RTEMS_TIMESLICE,
799                           RTEMS_DEFAULT_ATTRIBUTES,
800                           &softc_ptr->disp_param.task_id);
801  }
802  if (rc == RTEMS_SUCCESSFUL) {
803    rc = rtems_task_start(softc_ptr->disp_param.task_id,
804                          disp_hcms29xx_update_task,0);
805  }
806  return rc;
807}
808
809/*=========================================================================*\
810| Function:                                                                 |
811\*-------------------------------------------------------------------------*/
812rtems_device_driver disp_hcms29xx_dev_open
813(
814/*-------------------------------------------------------------------------*\
815| Purpose:                                                                  |
816|   open the display device                                                 |
817+---------------------------------------------------------------------------+
818| Input Parameters:                                                         |
819\*-------------------------------------------------------------------------*/
820  rtems_device_major_number  major,
821  rtems_device_minor_number  minor,
822  void                      *arg
823)
824/*-------------------------------------------------------------------------*\
825| Return Value:                                                             |
826|    rtems_status_code                                                      |
827\*=========================================================================*/
828{
829  disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
830  /*
831   * ensure, that disp_hcms29xx device is assumed to be empty
832   */
833  softc_ptr->disp_param.dev_buf_cnt = 0;
834
835  return RTEMS_SUCCESSFUL;
836}
837
838/*=========================================================================*\
839| Function:                                                                 |
840\*-------------------------------------------------------------------------*/
841rtems_device_driver disp_hcms29xx_dev_write
842(
843/*-------------------------------------------------------------------------*\
844| Purpose:                                                                  |
845|   write to display device                                                 |
846+---------------------------------------------------------------------------+
847| Input Parameters:                                                         |
848\*-------------------------------------------------------------------------*/
849  rtems_device_major_number  major,
850  rtems_device_minor_number  minor,
851  void                      *arg
852)
853/*-------------------------------------------------------------------------*\
854| Return Value:                                                             |
855|    rtems_status_code                                                      |
856\*=========================================================================*/
857{
858  rtems_libio_rw_args_t *args = arg;
859  uint32_t cnt;
860  disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
861
862  for (cnt = 0;cnt < args->count;cnt++) {
863    /*
864     * accumulate characters written into display dev buffer
865     */
866    if (((softc_ptr->disp_param.dev_buf_cnt > 0)
867        &&((args->buffer[cnt] == '\n')
868           || (args->buffer[cnt] == '\0'))
869         )
870        ||( softc_ptr->disp_param.dev_buf_cnt >=
871            (int) sizeof(softc_ptr->disp_param.dev_buffer) - 1)) {
872      softc_ptr->disp_param.dev_buffer[softc_ptr->disp_param.dev_buf_cnt] = '\0';
873      /*
874       * transfer string to display string, redisplay it...
875       */
876      disp_hcms29xx_update(softc_ptr,softc_ptr->disp_param.dev_buffer);
877      softc_ptr->disp_param.dev_buf_cnt = 0;
878    }
879    /*
880     * write to dev_buf, if '\n' occured or display device buffer is full
881     */
882    if ((args->buffer[cnt] != '\n') &&
883        (args->buffer[cnt] != '\0')) {
884      softc_ptr->disp_param.dev_buffer[softc_ptr->disp_param.dev_buf_cnt++] =
885        args->buffer[cnt];
886    }
887  }
888  args->bytes_moved = args->count;
889
890  return RTEMS_SUCCESSFUL;
891}
892
893/*=========================================================================*\
894| Function:                                                                 |
895\*-------------------------------------------------------------------------*/
896rtems_device_driver disp_hcms29xx_dev_close
897(
898/*-------------------------------------------------------------------------*\
899| Purpose:                                                                  |
900|   close the display device                                                |
901+---------------------------------------------------------------------------+
902| Input Parameters:                                                         |
903\*-------------------------------------------------------------------------*/
904  rtems_device_major_number  major,
905  rtems_device_minor_number  minor,
906  void                      *arg
907)
908/*-------------------------------------------------------------------------*\
909| Return Value:                                                             |
910|    rtems_status_code                                                      |
911\*=========================================================================*/
912{
913
914  return RTEMS_SUCCESSFUL;
915}
916
917/*
918 * driver operation tables
919 */
920static rtems_driver_address_table disp_hcms29xx_ops = {
921  .initialization_entry = disp_hcms29xx_dev_initialize,
922  .open_entry =           disp_hcms29xx_dev_open,
923  .write_entry =          disp_hcms29xx_dev_write,
924  .close_entry =          disp_hcms29xx_dev_close
925};
926
927
928static disp_hcms29xx_drv_t disp_hcms29xx_drv_tbl = {
929  {/* public fields */
930    .ops =         &disp_hcms29xx_ops, 
931    .size =        sizeof (disp_hcms29xx_drv_t),
932  },
933  { /* our private fields */
934  }
935};
936
937rtems_libi2c_drv_t *disp_hcms29xx_driver_descriptor = 
938  &disp_hcms29xx_drv_tbl.libi2c_drv_entry;
939
Note: See TracBrowser for help on using the repository browser.