brewpanel/slcd.c

Wed, 12 May 2021 21:17:59 +0200

author
Michiel Broek
date
Wed, 12 May 2021 21:17:59 +0200
changeset 611
732d482f47c8
parent 443
6b80a37fdf8d
child 637
21e542c15832
permissions
-rw-r--r--

Improved logging if wiringpi failed.

/*****************************************************************************
 * Copyright (C) 2015
 *   
 * Michiel Broek <mbroek at mbse dot eu>
 *
 * This file is part of the mbsePi-apps
 *
 * mbsePi-apps 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, or (at your option) any
 * later version.
 *
 * mbsePi-apps 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 mbsePi-apps; see the file COPYING.  If not, write to the Free
 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *****************************************************************************/

/*
 * Simulated LCD driver based on HD44780U displays.
 */

#include "brewpanel.h"
#include "sdlgui.h"
#include "slcd.h"
#include "dlgBrew.h"

#ifdef HAVE_SDL_SDL_H


// Bits in the control register
#define SLCD_BLINK_CTRL         0x01
#define SLCD_CURSOR_CTRL        0x02
#define SLCD_DISPLAY_CTRL       0x04

extern int	debug;


struct slcdDataStruct
{
    int 	x;		/* Start x pixels		*/
    int		y;		/* Start y pixels		*/
    int		w;		/* Width in pixels		*/
    int		h;		/* Height in pixels		*/
    int		cols;		/* Width in characters		*/
    int		rows;		/* Height in characters		*/
    int		cx;		/* Cursor x position		*/
    int		cy;		/* Cursor y position		*/
    Uint8	cgram[8][8];	/* Characters in CGRAM		*/
    int		control;	/* Control register		*/
};
struct slcdDataStruct *slcds [MAX_SLCDS] ;




void slcdHome(SGOBJ *dlg, int fd)
{
    struct slcdDataStruct *lcd = slcds [fd];

    lcd->cx = lcd->cy = 0;
    SDLGui_Cursor(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->control & SLCD_CURSOR_CTRL, lcd->control & SLCD_BLINK_CTRL);
}



void slcdClear(SGOBJ *dlg, int fd)
{
    struct slcdDataStruct *lcd = slcds [fd];
    int	i;

    lcd->cx = lcd->cy = 0;
    for (i = 0; i < (lcd->cols * lcd->rows); i++)
	slcdPutchar(dlg, fd, ' ');
    lcd->cx = lcd->cy = 0;
    SDLGui_Cursor(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->control & SLCD_CURSOR_CTRL, lcd->control & SLCD_BLINK_CTRL);
}



void slcdDisplay(SGOBJ *dlg, int fd, int state)
{
    struct slcdDataStruct *lcd = slcds [fd];

    if (state)
	lcd->control |= SLCD_DISPLAY_CTRL;
    else
	lcd->control &= ~SLCD_DISPLAY_CTRL;
}



void slcdCursor(SGOBJ *dlg, int fd, int state)
{
    struct slcdDataStruct *lcd = slcds [fd];

    if (state)
	lcd->control |= SLCD_CURSOR_CTRL;
    else
	lcd->control &= ~SLCD_CURSOR_CTRL;
    SDLGui_Cursor(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->control & SLCD_CURSOR_CTRL, lcd->control & SLCD_BLINK_CTRL);
}



void slcdCursorBlink(SGOBJ *dlg, int fd, int state)
{
    struct slcdDataStruct *lcd = slcds [fd];

    if (state)
	lcd->control |= SLCD_BLINK_CTRL;
    else
	lcd->control &= ~SLCD_BLINK_CTRL;
    SDLGui_Cursor(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->control & SLCD_CURSOR_CTRL, lcd->control & SLCD_BLINK_CTRL);
}



void slcdPosition(SGOBJ *dlg, int fd, int x, int y)
{
    struct slcdDataStruct *lcd = slcds [fd];

    if ((x > lcd->cols) || (x < 0))
	return ;
    if ((y > lcd->rows) || (y < 0))
	return ;

    lcd->cx = x ;
    lcd->cy = y ;
    SDLGui_Cursor(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->control & SLCD_CURSOR_CTRL, lcd->control & SLCD_BLINK_CTRL);
}



void slcdCharDef(SGOBJ *dlg, int fd, int index, Uint8 data[8])
{
    struct slcdDataStruct *lcd = slcds [fd];
    int i;

    for (i = 0 ; i < 8 ; i++) {
	lcd->cgram[index][i] = data[i];
    }
}




void slcdPutchar(SGOBJ *dlg, int fd, Uint8 data)
{
    struct slcdDataStruct *lcd = slcds [fd];

    if (data < 16)
	/*
	 * Character 0..7 and 8..15 are the same.
	 */
	SDLGui_CGChar(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->cgram[data & 0x07]);
    else
    	SDLGui_Char(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, data);

    if (++lcd->cx == lcd->cols) {
	lcd->cx = 0;
	if (++lcd->cy == lcd->rows)
	    lcd->cy = 0;
    }
    SDLGui_Cursor(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->control & SLCD_CURSOR_CTRL, lcd->control & SLCD_BLINK_CTRL);
}



void slcdPuts(SGOBJ *dlg, int fd, const char *string)
{
    while (*string)
	slcdPutchar(dlg, fd, *string++);
}



void slcdPrintf(SGOBJ *dlg, int fd, const char *message, ...)
{
    va_list	argp;
    char	buffer[1024];

    va_start(argp, message);
    vsnprintf(buffer, 1023, message, argp);
    va_end(argp);
    slcdPuts(dlg, fd, buffer);
}



void slcdBacklight(SGOBJ *dlg, int fd, int bl)
{
    if (debug)
    	fprintf(stdout, "slcdBacklight %d\n", bl);
    if (bl)
	dlg[1].state |= SG_SELECTED;
    else
	dlg[1].state &= ~SG_SELECTED;
    SDLGui_DrawLCD(dlg, 1);
}



void slcdLED(SGOBJ *dlg, int fd, int color, int state)
{
    SDLGui_LED(dlg, fd, color, state);
}



int slcdInit(SGOBJ *dlg, int fd, int x, int y, int w, int h, int cols, int rows)
{
    static int			initialised = 0;
    int				i, j;
    struct slcdDataStruct	*lcd;

    if (initialised == 0) {
	initialised = 1 ;
	for (i = 0 ; i < MAX_SLCDS ; ++i)
	    slcds[i] = NULL ;
    }

    if ((rows < 0) || (rows > 20))
	return -1 ;

    if ((cols < 0) || (cols > 20))
	return -1 ;

    /*
     * Create LCD
     */
    if (slcds[fd] != NULL) {
	syslog(LOG_NOTICE, "slcdInit fd=%d already in use", fd);
	return -1;
    }
    if ((lcd = (struct slcdDataStruct *)malloc (sizeof (struct slcdDataStruct))) == NULL) {
	return -1;
    }

    lcd->x = x;
    lcd->y = y;
    lcd->w = w;
    lcd->h = h;
    lcd->cols = cols;
    lcd->rows = rows;
    lcd->cx = 0;
    lcd->cy = 0;
    for (i = 0; i < 8; i++)
	for (j = 0; j < 8; j++)
	    lcd->cgram[i][j] = 0;
    lcd->control = 0;

    slcds[fd] = lcd;

    slcdDisplay(dlg, fd, TRUE);
    slcdCursor(dlg, fd, FALSE);
    slcdCursorBlink(dlg, fd, FALSE);
    slcdClear(dlg, fd);

    /*
     * Most LCD's start with the top row filled with blocks.
     */
    for (i = 0; i < lcd->cols; i++)
	slcdPutchar(dlg, fd, 0x0ff);

    slcdDisplay(dlg, fd, TRUE);
    slcdCursor(dlg, fd, FALSE);
    slcdCursorBlink(dlg, fd, FALSE);
    slcdClear(dlg, fd);

    return fd;
}


#endif

mercurial