Refactor BeRTOS to be in his own directory.
[bertos.git] / drv / lcd_text.c
diff --git a/drv/lcd_text.c b/drv/lcd_text.c
deleted file mode 100644 (file)
index 8e51928..0000000
+++ /dev/null
@@ -1,499 +0,0 @@
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction.  Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License.  This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Generic text LCD driver (impl.).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4  2006/09/20 20:02:43  marco
- *#* Replaced ISLISTEMPTY with LIST_EMPTY
- *#*
- *#* Revision 1.3  2006/07/19 12:56:25  bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.2  2006/02/24 00:27:14  bernie
- *#* Use new naming convention for list macros.
- *#*
- *#* Revision 1.1  2005/11/04 18:00:42  bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.11  2005/06/14 14:43:43  bernie
- *#* Add DevLib headers.
- *#*
- *#* Revision 1.10  2005/06/06 17:41:57  batt
- *#* Add lcd_layerSet function.
- *#*
- *#* Revision 1.9  2005/06/01 16:40:07  batt
- *#* Remove debug string.
- *#*
- *#* Revision 1.8  2005/06/01 16:38:04  batt
- *#* Adapt to changes in mware/list.h.
- *#*
- *#* Revision 1.7  2005/06/01 10:45:22  batt
- *#* lcd_setAddr(): Bugfix boundary condition; Misc cleanup.
- *#*
- *#* Revision 1.6  2005/06/01 10:36:23  batt
- *#* Layer: Rename member variables and Doxygenize.
- *#*
- *#* Revision 1.5  2005/05/27 11:05:58  batt
- *#* Do not write on lcd if layer is hidden.
- *#*/
-
-#include "lcd_text.h"
-#include "lcd_hd44.h"
-#include <drv/timer.h> // timer_delay()
-#include <mware/formatwr.h> // _formatted_write()
-#include <mware/list.h> // LIST_EMPTY()
-#include <cfg/macros.h> // BV()
-#include <cfg/debug.h>
-
-#include <string.h> // strlen()
-
-
-/** Maximum number of layers. */
-#define LCD_LAYERS 6
-
-#if CONFIG_KERNEL
-       /** Semaphore to arbitrate access to the display. */
-       static struct Semaphore lcd_semaphore;
-       #define LOCK_LCD        sem_obtain(&lcd_semaphore)
-       #define UNLOCK_LCD      sem_release(&lcd_semaphore)
-#else /* !CONFIG_KERNEL */
-       #define LOCK_LCD        do {} while (0)
-       #define UNLOCK_LCD      do {} while (0)
-#endif /* !CONFIG_KERNEL */
-
-DECLARE_LIST_TYPE(Layer);
-
-Layer *lcd_DefLayer;
-static Layer lcd_LayersPool[LCD_LAYERS];
-static LIST_TYPE(Layer) lcd_Layers;
-static LIST_TYPE(Layer) lcd_FreeLayers;
-
-/**
- * Current cursor status.
- *
- * One of LCD_CMD_CURSOR_OFF, LCD_CMD_CURSOR_BLOCK or LCD_CMD_CURSOR_LINE.
- */
-static uint8_t lcd_CursorStatus;
-
-/** Current cursor position, encoded as a Cursor position and status. */
-static lcdpos_t lcd_CursorAddr;
-
-
-void lcd_setAddr(Layer *layer, lcdpos_t addr)
-{
-       /* Sanity check: wrap around to display limits */
-       while (addr >= LCD_ROWS * LCD_COLS)
-               addr -= LCD_ROWS * LCD_COLS;
-
-       layer->addr = addr;
-}
-
-#if CONFIG_KERNEL
-
-void lcd_lock(void)
-{
-       LOCK_LCD;
-}
-
-
-void lcd_unlock(void)
-{
-       UNLOCK_LCD;
-}
-
-#endif /* CONFIG_KERNEL */
-
-
-/**
- * Write one character to the display at the current
- * cursor prosition, then move the cursor right. The
- * cursor is wrapped to the next line when it moves
- * beyond the end of the current line.
- *
- * \note Does _NOT_ lock the display semaphore.
- */
-static void lcd_putCharUnlocked(char c, Layer *layer)
-{
-       Layer *l2;
-       lcdpos_t addr = layer->addr;
-
-       /* Store character in layer buffer */
-       layer->buf[addr] = c;
-
-       /* Move to next character */
-       if (++layer->addr >= LCD_COLS * LCD_ROWS)
-               layer->addr = 0;
-
-       /* Do not write on LCD if layer is hidden. */
-       if (layer->pri == LAYER_HIDDEN)
-               return;
-
-       /*
-        * Check if this location is obscured by
-        * other layers above us.
-        */
-       for (l2 = layer->pred; l2->pred; l2 = l2->pred)
-       {
-               if (l2->buf[addr])
-               {
-                       /* DB(kprintf("layer %04x obs %04x at %d\n", l2, layer, addr);) */
-                       return;
-               }
-       }
-
-       /* Write character */
-       if (c)
-               lcd_putc(addr, c);
-       else
-               /* FIXME: should look for layers beneath! */
-               lcd_putc(addr, ' ');
-}
-
-
-void lcd_putChar(char c, Layer *layer)
-{
-       LOCK_LCD;
-       lcd_putCharUnlocked(c, layer);
-       UNLOCK_LCD;
-}
-
-void lcd_layerSet(Layer *layer, char c)
-{
-       int i;
-
-       LOCK_LCD;
-       lcd_setAddr(layer, 0);
-       for (i = 0; i < LCD_COLS * LCD_ROWS; i++)
-               lcd_putCharUnlocked(c, layer);
-       UNLOCK_LCD;
-}
-
-
-void lcd_clear(Layer *layer)
-{
-       lcd_layerSet(layer, 0);
-}
-
-
-void lcd_clearLine(Layer *layer, int y)
-{
-       int i;
-
-       LOCK_LCD;
-       lcd_setAddr(layer, LCD_POS(0, y));
-       for (i = 0; i < LCD_COLS; i++)
-               lcd_putCharUnlocked(0, layer);
-       UNLOCK_LCD;
-}
-
-
-void lcd_moveCursor(lcdpos_t addr)
-{
-       LOCK_LCD;
-       lcd_moveTo(addr);
-       UNLOCK_LCD;
-}
-
-
-char lcd_setCursor(char mode)
-{
-       static const char cursor_cmd[3] =
-       {
-               LCD_CMD_CURSOR_OFF, LCD_CMD_CURSOR_BLOCK, LCD_CMD_CURSOR_LINE
-       };
-       char oldmode = lcd_CursorStatus;
-
-       LOCK_LCD;
-       lcd_CursorStatus = mode;
-       lcd_setReg(cursor_cmd[(int)mode]);
-       if (mode)
-               lcd_moveCursor(lcd_CursorAddr);
-       UNLOCK_LCD;
-
-       return oldmode;
-}
-
-
-int lcd_vprintf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, va_list ap)
-{
-       int len;
-
-       LOCK_LCD;
-
-       /*
-        * Se il cursore era acceso, spegnilo durante
-        * l'output per evitare che salti alla posizione
-        * in cui si scrive.
-        */
-       if (lcd_CursorStatus)
-               lcd_setReg(LCD_CMD_CURSOR_OFF);
-
-       /* Spostamento del cursore */
-       lcd_setAddr(layer, addr);
-
-       if (mode & LCD_CENTER)
-       {
-               int pad;
-
-               /*
-                * NOTE: calculating the string lenght BEFORE it gets
-                * printf()-formatted. Real lenght may differ.
-                */
-               pad = (LCD_COLS - strlen(format)) / 2;
-               while (pad--)
-                       lcd_putCharUnlocked(' ', layer);
-       }
-
-       len = _formatted_write(format, (void (*)(char, void *))lcd_putCharUnlocked, layer, ap);
-
-       if (mode & (LCD_FILL | LCD_CENTER))
-               while (layer->addr % LCD_COLS)
-                       lcd_putCharUnlocked(' ', layer);
-
-       /*
-        * Riaccendi il cursore e riportalo alla
-        * vecchia posizione
-        */
-       if (lcd_CursorStatus)
-               lcd_setCursor(lcd_CursorStatus);
-
-       UNLOCK_LCD;
-
-       return len;
-}
-
-
-int lcd_printf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, ...)
-{
-       int len;
-       va_list ap;
-
-       va_start(ap, format);
-       len = lcd_vprintf(layer, addr, mode, format, ap);
-       va_end(ap);
-
-       return len;
-}
-
-
-/**
- * Internal function to move a layer between two positions.
- *
- * \note The layer must be *already* enqueued in some list.
- * \note The display must be already locked!
- */
-static void lcd_enqueueLayer(Layer *layer, char pri)
-{
-       Layer *l2;
-
-       /* Remove layer from whatever list it was in before */
-       REMOVE(layer);
-
-       layer->pri = pri;
-
-       /*
-        * Search for the first layer whose priority
-        * is less or equal to the layer we are adding.
-        */
-       FOREACH_NODE(l2, &lcd_Layers)
-               if (l2->pri <= pri)
-                       break;
-
-       /* Enqueue layer */
-       INSERT_BEFORE(layer, l2);
-}
-
-Layer *lcd_newLayer(char pri)
-{
-       Layer *layer;
-
-       LOCK_LCD;
-
-       if (LIST_EMPTY(&lcd_FreeLayers))
-       {
-               UNLOCK_LCD;
-               //ASSERT(false);
-               return NULL;
-       }
-
-       layer = (Layer *)LIST_HEAD(&lcd_FreeLayers);
-       layer->addr = 0;
-       memset(layer->buf, 0, LCD_ROWS * LCD_COLS);
-
-       lcd_enqueueLayer(layer, pri);
-
-       UNLOCK_LCD;
-       return layer;
-}
-
-/**
- * Redraw the display (internal).
- *
- * \note The display must be already locked.
- */
-static void lcd_refresh(void)
-{
-       lcdpos_t addr;
-       Layer *l;
-
-       for (addr = 0; addr < LCD_ROWS * LCD_COLS; ++addr)
-       {
-               FOREACH_NODE(l, &lcd_Layers)
-               {
-                       //kprintf("%d %x %p\n", addr, l->buf[0], l);
-                       if (l->pri == LAYER_HIDDEN)
-                               break;
-
-                       if (l->buf[addr])
-                       {
-                               /* Refresh location */
-                               lcd_putc(addr, l->buf[addr]);
-                               goto done;
-                       }
-               }
-
-               /* Draw background */
-               lcd_putc(addr, ' ');
-       done:
-               ;
-       }
-}
-
-/**
- * Rearrange layer depth and refresh display accordingly.
- *
- * \note Setting a priority of LAYER_HIDDEN makes the layer invisible.
- */
-void lcd_setLayerDepth(Layer *layer, char pri)
-{
-       if (pri != layer->pri)
-       {
-               LOCK_LCD;
-               lcd_enqueueLayer(layer, pri);
-               /* Vile but simple */
-               lcd_refresh();
-               UNLOCK_LCD;
-       }
-}
-
-void lcd_deleteLayer(Layer *layer)
-{
-       LOCK_LCD;
-
-/* We use lcd_refresh() instead.  Much simpler than this mess, but slower. */
-#if 0
-       Layer *l2;
-       lcdpos_t addr;
-
-       /* Repair damage on underlaying layers */
-       for (addr = 0; addr < LCD_ROWS * LCD_COLS; ++addr)
-       {
-               /* If location was covered by us */
-               if (layer->buf[addr])
-               {
-                       /* ...and it wasn't covered by others above us... */
-                       for (l2 = layer->pred; l2->pred; l2 = l2->pred)
-                               if (l2->buf[addr])
-                                       /* can't just break here! */
-                                       goto not_visible;
-
-                       /* ...scan underlaying layers to repair damage */
-                       for (l2 = layer->succ; l2->succ; l2 = l2->succ)
-                               if (l2->buf[addr])
-                               {
-                                       /* Refresh character */
-                                       lcd_putc(addr, l2->buf[addr]);
-
-                                       /* No need to search on deeper layers */
-                                       break;
-                               }
-
-                       not_visible:
-                               ;
-               }
-       }
-#endif
-
-       // Remove layer from lcd_Layers list.
-       REMOVE(layer);
-
-       /* Put layer back into free list */
-       ADDHEAD(&lcd_FreeLayers, layer);
-
-       lcd_refresh();
-
-       UNLOCK_LCD;
-}
-
-
-static void lcd_setDefLayer(Layer *layer)
-{
-       lcd_DefLayer = layer;
-}
-
-#include <cfg/debug.h>
-void lcd_init(void)
-{
-       int i;
-
-       LIST_INIT(&lcd_Layers);
-       LIST_INIT(&lcd_FreeLayers);
-       for (i = 0; i < LCD_LAYERS; ++i)
-               ADDHEAD(&lcd_FreeLayers, &lcd_LayersPool[i]);
-
-       lcd_setDefLayer(lcd_newLayer(0));
-
-       lcd_hw_init();
-
-       lcd_setCursor(0);
-}
-
-#if CONFIG_TEST
-void lcd_test(void)
-{
-       int i;
-
-       for (i = 0; i < LCD_ROWS * LCD_COLS; ++i)
-       {
-               lcd_putCharUnlocked('0' + (i % 10), lcd_DefLayer);
-               timer_delay(100);
-       }
-}
-#endif /* CONFIG_TEST */
-