Add driver for Samsung 16LF01 VFD display.

This commit is contained in:
Grzegorz Hetman 2016-02-23 15:00:23 +01:00
parent c1aa8f2e73
commit 54918803bb
6 changed files with 247 additions and 0 deletions

View file

@ -0,0 +1,3 @@
PROGRAM=vfd16lf01_counter
EXTRA_COMPONENTS = extras/vfd16lf01
include ../../common.mk

View file

@ -0,0 +1,44 @@
/*
* Simple cunter that is displayed on 16lf01 VFD display.
* Author: Grzegorz Hetman - ghetman@gmail.com
*/
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
// Samsung VFD 16lf01 driver
#include "vfd16lf01/vfd16lf01.h"
void counter(void *pvParameters)
{
uint8_t count = 0;
uint8_t pin_clk = 15;
uint8_t pin_rst = 13;
uint8_t pin_data = 0;
uint8_t digits = 16;
uint8_t brightness = 31; // Range 0-31
vfd_16lf01_init(pin_clk, pin_rst, pin_data, digits, brightness);
vfd_16lf01_print("ESP-OPEN-RTOS ;)", pin_clk, pin_data);
vTaskDelay(5000 / portTICK_RATE_MS);
while(1) {
char msg[16];
sprintf(msg, "Counter %d", count++);
printf("%s\n", msg);
vfd_16lf01_print(msg, pin_clk, pin_data);
vTaskDelay(250 / portTICK_RATE_MS);
}
}
void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
xTaskCreate(&counter, (signed char *)"counter", 256, NULL, 2, NULL);
}

7
extras/vfd16lf01/LICENSE Normal file
View file

@ -0,0 +1,7 @@
This is a driver for Samsung 16LF01 series VFD.
Originate written by Daniele Napolitano, distributed under GPL.
Ported by Grzegorz Hetman : ghetman@gmail.com
Daniele project site: https://github.com/DnaX/Samsung_16LF01_VFD

View file

@ -0,0 +1,9 @@
# Component makefile for extras/vfd16lf01
# expected anyone using bmp driver includes it as 'vfd16lf01/vfd16lf01.h'
INC_DIRS += $(vfd16lf01_ROOT)..
# args for passing into compile rule generation
vfd16lf01_SRC_DIR = $(vfd16lf01_ROOT)
$(eval $(call component_compile_rules,vfd16lf01))

View file

@ -0,0 +1,165 @@
#include "vfd16lf01.h"
#include <espressif/esp_misc.h> // sdk_os_delay_us
#define VFD_CMD_BUFFER_POINTER 0b10100000
#define VFD_CMD_DIGIT_COUNTER 0b11000000
#define VFD_CMD_MASK 0b00001111
#define VFD_CMD_BRIGHTNESS 0b11100000
#define VFD_CMD_BRIGHTNESS_MASK 0b00011111
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
static uint8_t _digits_count;
static void vfd_16lf01_command(uint8_t payload, uint8_t clk, uint8_t data){
static int8_t i=0;
// If you notice any strange issue with displayed payload
// please increase all delay value to 1~2ms.
#ifdef VIA_INVERTERS
for (i=7; i>=0; i--) {
if (bit_read(payload, i)){
gpio_write(data, 0);
} else {
gpio_write(data, 1);
}
gpio_write(clk, 0);
sdk_os_delay_us(500);
gpio_write(clk, 1);
sdk_os_delay_us(500);
gpio_write(clk, 0);
// Internal processing time (50us)
sdk_os_delay_us(50);
}
#else
for (i=7; i>=0; i--) {
if (bit_read(payload, i)){
gpio_write(data, 1);
} else {
gpio_write(data, 0);
}
gpio_write(clk, 1);
sdk_os_delay_us(500);
gpio_write(clk, 0);
sdk_os_delay_us(500);
gpio_write(clk, 1);
// Internal processing time (50us)
sdk_os_delay_us(50);
}
#endif
}
// Set number of digits to control.
static void vfd_16lf01_set_digits_count(uint8_t digits, uint8_t clk, uint8_t data) {
if (digits > 16) {
digits = 16;
}
_digits_count = digits;
digits &= VFD_CMD_MASK;
vfd_16lf01_command(VFD_CMD_DIGIT_COUNTER | digits, clk, data);
}
// Write a char on the display
static inline uint8_t vfd_16lf01_write(uint8_t _char, uint8_t clk, uint8_t data) {
// First set of charmap (letters ad some symbols)
if (_char >= 64 && _char <= 95) {
vfd_16lf01_command(_char - 64, clk, data);
}
// Second set of charmap (numbers and some symbols)
else if (_char >= 32 && _char <= 63) {
vfd_16lf01_command(_char, clk, data);
}
// Lower case letters
else if (_char >= 97 && _char <= 122) {
vfd_16lf01_command(_char - 96, clk, data);
}
return 1;
}
// Reset device.
void vfd_16lf01_reset(uint8_t rst){
#ifdef VIA_INVERTERS
gpio_write(rst, 1);
sdk_os_delay_us(500);
gpio_write(rst, 0);
sdk_os_delay_us(500);
#else
gpio_write(rst, 0);
sdk_os_delay_us(500);
gpio_write(rst, 1);
sdk_os_delay_us(500);
#endif
}
// Initialize device.
void vfd_16lf01_init(uint8_t clk, uint8_t rst, uint8_t data, uint8_t digits, uint8_t brightness) {
gpio_enable(clk, GPIO_OUTPUT);
gpio_enable(rst, GPIO_OUTPUT);
gpio_enable(data, GPIO_OUTPUT);
vfd_16lf01_reset(rst);
vfd_16lf01_set_digits_count(digits, clk, data);//16
vfd_16lf01_clear(clk, data);
vfd_16lf01_set_brightness(brightness, clk, data);//31
}
// Set buffer pointer position.
void vfd_16lf01_set_cursor(uint8_t pos, uint8_t clk, uint8_t data) {
if (pos > 15) {
pos = 15;
}
// First digit value is B1111, from second start from 0
if (pos == 0) {
pos = 0b1111;
}
else {
pos--;
}
pos &= VFD_CMD_MASK;
vfd_16lf01_command(VFD_CMD_BUFFER_POINTER | pos, clk, data);
}
// Set display brightness, from 0 to 31.
void vfd_16lf01_set_brightness(uint8_t amount, uint8_t clk, uint8_t data) {
if (amount > 31) {
amount = 31;
}
amount &= VFD_CMD_BRIGHTNESS_MASK;
vfd_16lf01_command(VFD_CMD_BRIGHTNESS | amount, clk, data);
}
// Return to position 1
void vfd_16lf01_home(uint8_t clk, uint8_t data) {
vfd_16lf01_set_cursor(0, clk, data);
}
// Blank the display by setting up to 16 spaces
void vfd_16lf01_clear(uint8_t clk, uint8_t data) {
static uint8_t i = 0;
vfd_16lf01_set_cursor(0, clk, data);
for (i=0; i<_digits_count; i++) {
vfd_16lf01_write(' ', clk, data);
}
}
void vfd_16lf01_print(char *chp, uint8_t clk, uint8_t data) {
uint8_t i = 0;
vfd_16lf01_home(clk, data);
while (*chp){
vfd_16lf01_write(*chp++, clk, data);
i++;
}
// Clear the rest cells that can display old characters.
for (;i < _digits_count; i++) {
vfd_16lf01_write(' ', clk, data);
}
}

View file

@ -0,0 +1,19 @@
#ifndef DRIVER_VFD16LF01_H_
#define DRIVER_VFD16LF01_H_
#include "FreeRTOS.h"
// Comment this out, if your display
// is connected directly to esp module,
// otherwise all signals will be inverted.
#define VIA_INVERTERS
void vfd_16lf01_init(uint8_t clk, uint8_t rst, uint8_t dat, uint8_t digits, uint8_t brightness);
void vfd_16lf01_set_brightness(uint8_t amount, uint8_t clk, uint8_t data);
void vfd_16lf01_set_cursor(uint8_t pos, uint8_t clk, uint8_t data);
void vfd_16lf01_print(char *chp, uint8_t clk, uint8_t data);
void vfd_16lf01_clear(uint8_t clk, uint8_t data);
void vfd_16lf01_home(uint8_t clk, uint8_t data);
void vfd_16lf01_reset(uint8_t rst);
#endif