source: rtems/c/src/libchip/display/disp_hcms29xx.c @ 9e621f6

4.115
Last change on this file since 9e621f6 was 9e621f6, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/20/11 at 15:35:40

2011-10-20 Ralf Corsépius <ralf.corsepius@…>

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