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

4.104.114.9
Last change on this file since 9bd5118 was 9bd5118, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 17, 2008 at 2:39:34 PM

fixes for display driver

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