1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers: added driver for PCD8544 LCD display

This commit is contained in:
Hauke Petersen 2015-04-28 15:56:46 +02:00 committed by haukepetersen
parent 86d44970c7
commit 3778fb3dde
5 changed files with 645 additions and 0 deletions

View File

@ -46,3 +46,6 @@ endif
ifneq (,$(filter ina220,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ina220/include
endif
ifneq (,$(filter pcd8544,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/pcd8544/include
endif

202
drivers/include/pcd8544.h Normal file
View File

@ -0,0 +1,202 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup driver_pcd8544 PCD8544 LCD driver
* @ingroup drivers
* @brief Driver for PCD8544 LCD displays
*
* @{
*
* @file
* @brief Interface definition for the PCD8544 LCD driver
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __PDC8544_H
#define __PDC8544_H
#include <stdint.h>
#include "periph/gpio.h"
#include "periph/spi.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Definition of display dimensions
* @{
*/
#define PCD8544_RES_X (84U) /**< pixels per row */
#define PCD8544_RES_Y (48U) /**< pixels per column */
#define PCD8544_COLS (14U) /**< characters per row */
#define PCD8544_ROWS (6U) /**< characters per column */
/** @} */
/**
* @brief Default values for temperature compensation and contrast
* @{
*/
#define PCD8544_DEFAULT_CONTRAST (45U)
#define PCD8544_DEFAULT_BIAS (3U)
#define PCD8544_DEFAULT_TEMPCOEF (0U)
/** @} */
/**
* @brief PCD8544 device descriptor
*/
typedef struct {
spi_t spi; /**< SPI bus the display is connected to */
gpio_t cs; /**< chip-select pin, low: active */
gpio_t reset; /**< reset pin, low: active */
gpio_t mode; /**< mode pin: low: cmd mode, high: data mode */
uint8_t inverted; /**< internal flag to keep track of inversion state */
} pcd8544_t;
/**
* @brief Initialize the given display
*
* @param[in] dev device descriptor of display to use
* @param[in] spi SPI bus the display is connected to
* @param[in] cs GPIO pin that is connected to the CS pin
* @param[in] reset GPIO pin that is connected to the RESET pin
* @param[in] mode GPIO pin that is connected to the MODE pin
*
* @return 0 on success
* @return <0 on error
*/
int pcd8544_init(pcd8544_t *dev, spi_t spi, gpio_t cs,
gpio_t reset, gpio_t mode);
/**
* @brief Set the contrast for the given display
*
* @note A contrast value of 45 yields good results for 3V3
*
* @param[in] dev display device descriptor
* @param[in] contrast targeted contrast value [0 - 127]
*/
void pcd8544_set_contrast(pcd8544_t *dev, uint8_t contrast);
/**
* @brief Set the temperature coefficient for the given display
*
* @note Look at the datasheet for more information
*
* @param[in] dev device descriptor of display to use
* @param[in] coef temperature coefficient to use [0 - 3]
*/
void pcd8544_set_tempcoef(pcd8544_t *dev, uint8_t coef);
/**
* @brief Set the internal BIAS for the given display
*
* @note Look at the datasheet for more information
*
* @param[in] dev device descriptor of display to use
* @param[in] bias the BIAS to use [0 - 7]
*
*/
void pcd8544_set_bias(pcd8544_t *dev, uint8_t bias);
/**
* @brief Write an image to memory of the given display
*
* The image must be given as a char array with 504 elements. Each bit in the
* array represents one pixel on the display. Each byte in the array contains
* 8 stacked pixels, from top to bottom. So byte[0] contains the pixels from
* (0,0) to (0,7), byte[1] (1,0) to (1,7) and byte[503] the pixels from
* (83,40) to (83,47) -> see the 'horizontal addressing' section in the
* datasheet.
*
* @param[in] dev device descriptor of display to use
* @param[in] img char array with image data (must be of size := 504)
*/
void pcd8544_write_img(pcd8544_t *dev, const char img[]);
/**
* @brief Write a single ASCII character to the display
*
* The position of the character is specified in columns (x) and rows (y)
*
* @param[in] dev device descriptor of display to use
* @param[in] x column to put the character [0 - 13]
* @param[in] y row to put the character [0 - 5]
* @param[in] c ASCII code for the character to write
*/
void pcd8544_write_c(pcd8544_t *dev, uint8_t x, uint8_t y, const char c);
/**
* @brief Write a string to a given position on the display
*
* This function prints a given string to the given position on the display. The
* position is given in terms of columns (x) and rows (y). If a string does not
* fit completely in the given position (it overflows its row), the overflowing
* part of the string is cut off.
*
* @param[in] dev device descriptor of display to use
* @param[in] x starting column of the string [0 - 13]
* @param[in] y row to write the string to [0 - 5]
* @param[in] str string to write to the display
*/
void pcd8544_write_s(pcd8544_t *dev, uint8_t x, uint8_t y, const char* str);
/**
* @brief Clear the current display (clear the display memory)
*
* @param[in] dev device descriptor of display to use
*/
void pcd8544_clear(pcd8544_t *dev);
/**
* @brief Invert the display (toggles dark and bright pixels)
*
* @param[in] dev device descriptor of display to use
*/
void pcd8544_invert(pcd8544_t *dev);
/**
* @brief Get the current inversion status of the display
*
* @param[in] dev device descriptor of display to use
*
* @return 0 -> display is not inverted
* @return 1 -> display is inverted
*/
int pcd8544_is_inverted(pcd8544_t *dev);
/**
* @brief Power on the display
*
* @param[in] dev device descriptor of display to use
*/
void pcd8544_poweron(pcd8544_t *dev);
/**
* @brief Poser off the display
*
* @param[in] dev device descriptor of display to use
*/
void pcd8544_poweroff(pcd8544_t *dev);
/**
* @brief I wonder what this does -> find out!
*
* @param[in] dev device descriptor of display to use
*/
void pcd8544_riot(pcd8544_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* __PDC8544_H */
/** @} */

1
drivers/pcd8544/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup driver_pcd8544
*
* @{
*
* @file
* @brief Internal definitions for PCD8544 displays
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef PDC8544_INTERNAL_H
#define PDC8544_INTERNAL_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Delay for resetting the device
*/
#define RESET_DELAY (5000) /* keep reset low for 5ms */
/**
* @brief Communication modes: command or data
* @{
*/
#define MODE_CMD (0) /**< we are sending a command */
#define MODE_DTA (1) /**< we are sending some data */
/** @} */
/**
* @brief Maximum parameter values
* @{
*/
#define CONTRAST_MAX (127U) /**< maximum possible contrast value */
#define TEMP_MAX (3U) /**< maximum possible temp coefficient */
#define BIAS_MAX (7U) /**< maximum possible bias value */
/** @} */
/**
* @brief Display commands
* @{
*/
#define CMD_DISABLE (0x24) /**< set LCD into power down mode */
#define CMD_ENABLE_H (0x20) /**< ON using horizontal addressing */
#define CMD_ENABLE_V (0x22) /**< ON using vertical addressing */
#define CMD_EXTENDED (0x21) /**< enter extended instruction set mode */
#define CMD_MODE_BLANK (0x08) /**< display nothing */
#define CMD_MODE_NORMAL (0x0c) /**< display memory content */
#define CMD_MODE_ALLON (0x09) /**< display 'black' screen */
#define CMD_MODE_INVERSE (0x0d) /**< display inverted memory content */
#define CMD_SET_Y (0x40) /**< set 3-bit y address, OR with Y value */
#define CMD_SET_X (0x80) /**< set 7-bit x address, OR with X value */
#define CMD_EXT_TEMP (0x04) /**< select temperature coefficient */
#define CMD_EXT_BIAS (0x10) /**< select BIAS value */
#define CMD_EXT_CONTRAST (0x80) /**< set contrast, OR with [0 - 127] */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* PDC8544_INTERNAL_H */
/** @} */

363
drivers/pcd8544/pcd8544.c Normal file
View File

@ -0,0 +1,363 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_pcd8544
* @{
* @file
* @brief Implementation of the SPI driver for the PDC8544 graphics display
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include <stdint.h>
#include <stdio.h>
#include "hwtimer.h"
#include "periph/spi.h"
#include "periph/gpio.h"
#include "pcd8544.h"
#include "pcd8544_internal.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define ASCII_MIN 0x20 /**< start of ASCII table */
#define ASCII_MAX 0x7e /**< end of ASCII table */
#define CHAR_WIDTH (6U) /**< pixel width of a single character */
static const uint8_t _ascii[][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00},/* 20 SPACE*/
{0x00, 0x00, 0x5f, 0x00, 0x00},/* 21 ! */
{0x00, 0x07, 0x00, 0x07, 0x00},/* 22 " */
{0x14, 0x7f, 0x14, 0x7f, 0x14},/* 23 # */
{0x24, 0x2a, 0x7f, 0x2a, 0x12},/* 24 $ */
{0x23, 0x13, 0x08, 0x64, 0x62},/* 25 % */
{0x36, 0x49, 0x55, 0x22, 0x50},/* 26 & */
{0x00, 0x05, 0x03, 0x00, 0x00},/* 27 ' */
{0x00, 0x1c, 0x22, 0x41, 0x00},/* 28 ( */
{0x00, 0x41, 0x22, 0x1c, 0x00},/* 29 ) */
{0x14, 0x08, 0x3e, 0x08, 0x14},/* 2a * */
{0x08, 0x08, 0x3e, 0x08, 0x08},/* 2b + */
{0x00, 0x50, 0x30, 0x00, 0x00},/* 2c , */
{0x08, 0x08, 0x08, 0x08, 0x08},/* 2d - */
{0x00, 0x60, 0x60, 0x00, 0x00},/* 2e . */
{0x20, 0x10, 0x08, 0x04, 0x02},/* 2f / */
{0x3e, 0x51, 0x49, 0x45, 0x3e},/* 30 0 */
{0x00, 0x42, 0x7f, 0x40, 0x00},/* 31 1 */
{0x42, 0x61, 0x51, 0x49, 0x46},/* 32 2 */
{0x21, 0x41, 0x45, 0x4b, 0x31},/* 33 3 */
{0x18, 0x14, 0x12, 0x7f, 0x10},/* 34 4 */
{0x27, 0x45, 0x45, 0x45, 0x39},/* 35 5 */
{0x3c, 0x4a, 0x49, 0x49, 0x30},/* 36 6 */
{0x01, 0x71, 0x09, 0x05, 0x03},/* 37 7 */
{0x36, 0x49, 0x49, 0x49, 0x36},/* 38 8 */
{0x06, 0x49, 0x49, 0x29, 0x1e},/* 39 9 */
{0x00, 0x36, 0x36, 0x00, 0x00},/* 3a : */
{0x00, 0x56, 0x36, 0x00, 0x00},/* 3b ; */
{0x08, 0x14, 0x22, 0x41, 0x00},/* 3c < */
{0x14, 0x14, 0x14, 0x14, 0x14},/* 3d = */
{0x00, 0x41, 0x22, 0x14, 0x08},/* 3e > */
{0x02, 0x01, 0x51, 0x09, 0x06},/* 3f ? */
{0x32, 0x49, 0x79, 0x41, 0x3e},/* 40 @ */
{0x7e, 0x11, 0x11, 0x11, 0x7e},/* 41 A */
{0x7f, 0x49, 0x49, 0x49, 0x36},/* 42 B */
{0x3e, 0x41, 0x41, 0x41, 0x22},/* 43 C */
{0x7f, 0x41, 0x41, 0x22, 0x1c},/* 44 D */
{0x7f, 0x49, 0x49, 0x49, 0x41},/* 45 E */
{0x7f, 0x09, 0x09, 0x09, 0x01},/* 46 F */
{0x3e, 0x41, 0x49, 0x49, 0x7a},/* 47 G */
{0x7f, 0x08, 0x08, 0x08, 0x7f},/* 48 H */
{0x00, 0x41, 0x7f, 0x41, 0x00},/* 49 I */
{0x20, 0x40, 0x41, 0x3f, 0x01},/* 4a J */
{0x7f, 0x08, 0x14, 0x22, 0x41},/* 4b K */
{0x7f, 0x40, 0x40, 0x40, 0x40},/* 4c L */
{0x7f, 0x02, 0x0c, 0x02, 0x7f},/* 4d M */
{0x7f, 0x04, 0x08, 0x10, 0x7f},/* 4e N */
{0x3e, 0x41, 0x41, 0x41, 0x3e},/* 4f O */
{0x7f, 0x09, 0x09, 0x09, 0x06},/* 50 P */
{0x3e, 0x41, 0x51, 0x21, 0x5e},/* 51 Q */
{0x7f, 0x09, 0x19, 0x29, 0x46},/* 52 R */
{0x46, 0x49, 0x49, 0x49, 0x31},/* 53 S */
{0x01, 0x01, 0x7f, 0x01, 0x01},/* 54 T */
{0x3f, 0x40, 0x40, 0x40, 0x3f},/* 55 U */
{0x1f, 0x20, 0x40, 0x20, 0x1f},/* 56 V */
{0x3f, 0x40, 0x38, 0x40, 0x3f},/* 57 W */
{0x63, 0x14, 0x08, 0x14, 0x63},/* 58 X */
{0x07, 0x08, 0x70, 0x08, 0x07},/* 59 Y */
{0x61, 0x51, 0x49, 0x45, 0x43},/* 5a Z */
{0x00, 0x7f, 0x41, 0x41, 0x00},/* 5b [ */
{0x02, 0x04, 0x08, 0x10, 0x20},/* 5c \ */
{0x00, 0x41, 0x41, 0x7f, 0x00},/* 5d ] */
{0x04, 0x02, 0x01, 0x02, 0x04},/* 5e ^ */
{0x40, 0x40, 0x40, 0x40, 0x40},/* 5f _ */
{0x00, 0x01, 0x02, 0x04, 0x00},/* 60 ` */
{0x20, 0x54, 0x54, 0x54, 0x78},/* 61 a */
{0x7f, 0x48, 0x44, 0x44, 0x38},/* 62 b */
{0x38, 0x44, 0x44, 0x44, 0x20},/* 63 c */
{0x38, 0x44, 0x44, 0x48, 0x7f},/* 64 d */
{0x38, 0x54, 0x54, 0x54, 0x18},/* 65 e */
{0x08, 0x7e, 0x09, 0x01, 0x02},/* 66 f */
{0x0c, 0x52, 0x52, 0x52, 0x3e},/* 67 g */
{0x7f, 0x08, 0x04, 0x04, 0x78},/* 68 h */
{0x00, 0x44, 0x7d, 0x40, 0x00},/* 69 i */
{0x20, 0x40, 0x44, 0x3d, 0x00},/* 6a j */
{0x7f, 0x10, 0x28, 0x44, 0x00},/* 6b k */
{0x00, 0x41, 0x7f, 0x40, 0x00},/* 6c l */
{0x7c, 0x04, 0x18, 0x04, 0x78},/* 6d m */
{0x7c, 0x08, 0x04, 0x04, 0x78},/* 6e n */
{0x38, 0x44, 0x44, 0x44, 0x38},/* 6f o */
{0x7c, 0x14, 0x14, 0x14, 0x08},/* 70 p */
{0x08, 0x14, 0x14, 0x18, 0x7c},/* 71 q */
{0x7c, 0x08, 0x04, 0x04, 0x08},/* 72 r */
{0x48, 0x54, 0x54, 0x54, 0x20},/* 73 s */
{0x04, 0x3f, 0x44, 0x40, 0x20},/* 74 t */
{0x3c, 0x40, 0x40, 0x20, 0x7c},/* 75 u */
{0x1c, 0x20, 0x40, 0x20, 0x1c},/* 76 v */
{0x3c, 0x40, 0x30, 0x40, 0x3c},/* 77 w */
{0x44, 0x28, 0x10, 0x28, 0x44},/* 78 x */
{0x0c, 0x50, 0x50, 0x50, 0x3c},/* 79 y */
{0x44, 0x64, 0x54, 0x4c, 0x44},/* 7a z */
{0x00, 0x08, 0x36, 0x41, 0x00},/* 7b { */
{0x00, 0x00, 0x7f, 0x00, 0x00},/* 7c | */
{0x00, 0x41, 0x36, 0x08, 0x00},/* 7d } */
{0x10, 0x08, 0x08, 0x10, 0x08},/* 7e ~ */
};
static const char _riot[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfc, 0x7e,
0x3e, 0x3e, 0x1f, 0x1f, 0x1f, 0x1f, 0x3f, 0x3e,
0x7e, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfc,
0x7e, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc0, 0xf0, 0xf8, 0xfc, 0xfe, 0x3f,
0x1f, 0x0f, 0x0f, 0x07, 0x07, 0x07, 0x03, 0x03,
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x83,
0x81, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x0f, 0x3f, 0xff, 0xff,
0xfc, 0xf0, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x7e,
0x7c, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x78,
0x7c, 0x7e, 0x3f, 0x3f, 0x1f, 0x0f, 0x07, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x0f, 0x1f, 0x3f, 0x3f,
0x1f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static void _write(pcd8544_t *dev, uint8_t is_data, char data)
{
/* set command or data mode */
gpio_write(dev->mode, is_data);
/* write byte to LCD */
spi_acquire(dev->spi);
gpio_clear(dev->cs);
spi_transfer_byte(dev->spi, data, 0);
gpio_set(dev->cs);
spi_release(dev->spi);
}
static inline void _set_x(pcd8544_t *dev, uint8_t x)
{
_write(dev, MODE_CMD, CMD_SET_X | x);
}
static inline void _set_y(pcd8544_t *dev, uint8_t y)
{
_write(dev, MODE_CMD, CMD_SET_Y | y);
}
int pcd8544_init(pcd8544_t *dev, spi_t spi, gpio_t cs, gpio_t reset, gpio_t mode)
{
/* save pin mapping */
dev->spi = spi;
dev->cs = cs;
dev->reset = reset;
dev->mode = mode;
dev->inverted = 0;
DEBUG("done setting dev members\n");
/* initialze pins */
gpio_init_out(cs, GPIO_NOPULL);
gpio_init_out(reset, GPIO_NOPULL);
gpio_init_out(mode, GPIO_NOPULL);
DEBUG("done with gpios\n");
/* clear CS line */
gpio_set(cs);
DEBUG("done clearing CS line\n");
/* initialize SPI */
spi_init_master(spi, SPI_CONF_FIRST_RISING, SPI_SPEED_1MHZ);
DEBUG("done initializing SPI master\n");
/* reset display */
gpio_clear(reset);
hwtimer_wait(RESET_DELAY);
gpio_set(reset);
/* clear display memory */
pcd8544_clear(dev);
/* write initialization sequence to display */
pcd8544_set_contrast(dev, PCD8544_DEFAULT_CONTRAST);
pcd8544_set_bias(dev, PCD8544_DEFAULT_BIAS);
pcd8544_set_tempcoef(dev, PCD8544_DEFAULT_TEMPCOEF);
/* enable display */
_write(dev, MODE_CMD, CMD_ENABLE_H);
_write(dev, MODE_CMD, CMD_MODE_NORMAL);
return 0;
}
void pcd8544_set_contrast(pcd8544_t *dev, uint8_t contrast)
{
if (contrast > CONTRAST_MAX) {
contrast = CONTRAST_MAX;
}
_write(dev, MODE_CMD, CMD_EXTENDED);
_write(dev, MODE_CMD, (CMD_EXT_CONTRAST | contrast));
_write(dev, MODE_CMD, CMD_ENABLE_H);
}
void pcd8544_set_tempcoef(pcd8544_t *dev, uint8_t coef)
{
if (coef > TEMP_MAX) {
coef = TEMP_MAX;
}
_write(dev, MODE_CMD, CMD_EXTENDED);
_write(dev, MODE_CMD, (CMD_EXT_TEMP | coef));
_write(dev, MODE_CMD, CMD_ENABLE_H);
}
void pcd8544_set_bias(pcd8544_t *dev, uint8_t bias)
{
if (bias > BIAS_MAX) {
bias = BIAS_MAX;
}
_write(dev, MODE_CMD, CMD_EXTENDED);
_write(dev, MODE_CMD, (CMD_EXT_BIAS | bias));
_write(dev, MODE_CMD, CMD_ENABLE_H);
}
void pcd8544_riot(pcd8544_t *dev)
{
pcd8544_write_img(dev, _riot);
}
void pcd8544_write_img(pcd8544_t *dev, const char img[])
{
/* set initial position */
_set_x(dev, 0);
_set_y(dev, 0);
/* write image data to display */
for (int i = 0; i < (PCD8544_RES_X * PCD8544_RES_Y / 8); i++) {
_write(dev, MODE_DTA, img[i]);
}
}
void pcd8544_write_c(pcd8544_t *dev, uint8_t x, uint8_t y, char c)
{
/* check position */
if (x >= PCD8544_COLS || y >= PCD8544_ROWS) {
return ;
}
/* set position */
_set_x(dev, x * CHAR_WIDTH);
_set_y(dev, y);
/* write char */
for (int i = 0; i < CHAR_WIDTH - 1; i++) {
_write(dev, MODE_DTA, _ascii[c - ASCII_MIN][i]);
}
_write(dev, MODE_DTA, 0x00);
}
void pcd8544_write_s(pcd8544_t *dev, uint8_t x, uint8_t y, const char *s)
{
for (; (*s != '\0') && x < PCD8544_COLS; x++, s++) {
pcd8544_write_c(dev, x, y, *s);
}
}
void pcd8544_clear(pcd8544_t *dev)
{
_set_x(dev, 0);
_set_y(dev, 0);
for (int i = 0; i < PCD8544_RES_X * PCD8544_ROWS; i++) {
_write(dev, MODE_DTA, 0x00);
}
}
void pcd8544_invert(pcd8544_t *dev)
{
if (dev->inverted) {
_write(dev, MODE_CMD, CMD_MODE_NORMAL);
}
else {
_write(dev, MODE_CMD, CMD_MODE_INVERSE);
}
dev->inverted ^= 0x01;
}
int pcd8544_is_inverted(pcd8544_t *dev)
{
return dev->inverted;
}
void pcd8544_poweron(pcd8544_t *dev)
{
_write(dev, MODE_CMD, CMD_ENABLE_H);
}
void pcd8544_poweroff(pcd8544_t *dev)
{
_write(dev, MODE_CMD, CMD_DISABLE);
}