source: rtems/c/src/libchip/display/disp_hcms29xx.c @ 0ad1e80

4.115
Last change on this file since 0ad1e80 was 0ad1e80, checked in by Josh Oguin <josh.oguin@…>, on 11/19/14 at 20:26:58

libchip/display/disp_hcms29xx.c: Remove useless variable and check

This was flagged by CodeSonar?.

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