mirror of
https://github.com/cclassic/hcs12ss59t
synced 2025-02-14 03:05:06 +01:00
263 lines
6.2 KiB
C
263 lines
6.2 KiB
C
/*
|
|
* HCS12SS59T AVR Library
|
|
* Copyright (c) 2017 Markus Koch <markus@notsyncing.net>
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "hcs12ss59t.h"
|
|
|
|
/**
|
|
* @brief hcs12ss59t_get_char Converts an ASCII character to the code used by the display
|
|
* @param c the character to be converted
|
|
* @return the converted character
|
|
*/
|
|
char hcs12ss59t_get_char(char c)
|
|
{
|
|
if (c >= '@' && c <= '_')
|
|
c -= 48;
|
|
else if (c >= ' ' && c <= '?')
|
|
c += 16;
|
|
else if (c >= 'a' && c <= 'z')
|
|
c -= 80;
|
|
else if (c == 0) {
|
|
c = ' ' - 48;
|
|
}
|
|
else
|
|
c = 79;
|
|
return c;
|
|
}
|
|
|
|
/**
|
|
* @brief hc12ss59t_init Initializes the I/O ports and SPI master
|
|
*/
|
|
void hcs12ss59t_init()
|
|
{
|
|
HCS12SS59T_SPI_DDR = (1 << HCS12SS59T_SPI_MOSI) |
|
|
(1 << HCS12SS59T_SPI_SCK) |
|
|
(1 << HCS12SS59T_SPI_SS_N) |
|
|
(1 << HCS12SS59T_SPI_RESET_N);
|
|
SPCR = (1 << SPE) | (1 << MSTR) | (1 << DORD) | (1 << SPR0);
|
|
|
|
hcs12ss59t_reset();
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_send_byte sends a byte over SPI
|
|
* @param c the data byte
|
|
*/
|
|
void hcs12ss59t_send_byte(char c)
|
|
{
|
|
SPDR = c;
|
|
while(!(SPSR & (1<<SPIF)));
|
|
_delay_us(8);
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_send_cmd Selects the device, sends the command and deselects the device
|
|
* @param cmd the command
|
|
* @param arg any arguments. Use 0 if none are required
|
|
*/
|
|
void hcs12ss59t_send_cmd(char cmd, char arg)
|
|
{
|
|
HCS12SS59T_SELECT;
|
|
hcs12ss59t_send_byte(cmd | (arg & 0x0f));
|
|
HCS12SS59T_DESELECT;
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_set_brightness Set the brightness of the VFD
|
|
* @param brightness brightness level (0 - 15)
|
|
*/
|
|
void hcs12ss59t_set_brightness(char brightness)
|
|
{
|
|
hcs12ss59t_send_cmd(HCS12SS59T_DUTY, brightness);
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_reset Performs a reset of the display controller
|
|
*/
|
|
void hcs12ss59t_reset()
|
|
{
|
|
/* Perform a HW reset */
|
|
HCS12SS59T_SPI_PORT &= ~(1 << HCS12SS59T_SPI_RESET_N);
|
|
_delay_us(1); /* > 250 ns */
|
|
HCS12SS59T_SPI_PORT |= (1 << HCS12SS59T_SPI_RESET_N);
|
|
_delay_us(1); /* > 250 ns */
|
|
|
|
/* Configure controlller for VFD */
|
|
hcs12ss59t_send_cmd(HCS12SS59T_NUMDIGIT, HCS12SS59T_NUMDIGITS);
|
|
hcs12ss59t_set_lights(HCS12SS59T_LINORM);
|
|
hcs12ss59t_set_brightness(HCS12SS59T_DEFAULT_BRIGHTNESS);
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_set_text update the text on the display
|
|
* @param text a text buffer with size HCS12SS59T_NUMDIGITS
|
|
*/
|
|
void hcs12ss59t_set_text(char *text)
|
|
{
|
|
char *ptr;
|
|
|
|
HCS12SS59T_SELECT;
|
|
hcs12ss59t_send_byte(HCS12SS59T_DCRAM_WR);
|
|
for (ptr = text + HCS12SS59T_NUMDIGITS - 1; ptr >= text; --ptr) {
|
|
hcs12ss59t_send_byte(hcs12ss59t_get_char(*ptr));
|
|
}
|
|
HCS12SS59T_DESELECT;
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_set_text update the text on the display without applying any character transformations
|
|
* @param data a buffer with size HCS12SS59T_NUMDIGITS
|
|
*/
|
|
void hcs12ss59t_set_buffer(char *data)
|
|
{
|
|
char *ptr;
|
|
|
|
HCS12SS59T_SELECT;
|
|
hcs12ss59t_send_byte(HCS12SS59T_DCRAM_WR);
|
|
for (ptr = data + HCS12SS59T_NUMDIGITS - 1; ptr >= data; --ptr) {
|
|
hcs12ss59t_send_byte(*ptr);
|
|
}
|
|
HCS12SS59T_DESELECT;
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_set_character set user configurable characters
|
|
* @param addr character number (0 - 15)
|
|
* @param data data array, 2 bytes per character
|
|
* @param nchar Amount of characters to update (auto increment)
|
|
*/
|
|
void hcs12ss59t_set_character(int addr, char *data, int nchar)
|
|
{
|
|
char *ptr;
|
|
|
|
nchar = nchar * 2;
|
|
|
|
HCS12SS59T_SELECT;
|
|
hcs12ss59t_send_byte(HCS12SS59T_CGRAM_WR | (addr & 0x0f));
|
|
for (ptr = data; ptr < data + nchar; ++ptr) {
|
|
hcs12ss59t_send_byte(*ptr);
|
|
}
|
|
HCS12SS59T_DESELECT;
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_set_lights Set the display mode to on, off or test
|
|
* @param lights value, use constants HCS12SS59T_LI*
|
|
*/
|
|
void hcs12ss59t_set_lights(char lights)
|
|
{
|
|
hcs12ss59t_send_cmd(HCS12SS59T_LIGHTS, lights);
|
|
}
|
|
|
|
const char hcs12ss59t_bar_styles[2][5][2] = {
|
|
{
|
|
{0x84, 0x83}, // Full on
|
|
{0x80, 0x00}, // 1
|
|
{0x80, 0x80}, // 2
|
|
{0x80, 0x81}, // 3
|
|
{0x80, 0x83} // 4
|
|
},
|
|
{
|
|
{0x48, 0x38}, // Full on
|
|
{0x40, 0x00}, // 1
|
|
{0x40, 0x20}, // 2
|
|
{0x40, 0x30}, // 3
|
|
{0x40, 0x38} // 4
|
|
}
|
|
};
|
|
|
|
const char hcs12ss59t_tick_styles[2][5][2] = {
|
|
{
|
|
{0x80, 0x00}, // 1
|
|
{0x00, 0x80}, // 2
|
|
{0x00, 0x01}, // 3
|
|
{0x00, 0x02}, // 4
|
|
{0x04, 0x00} // 5
|
|
},
|
|
{
|
|
{0x40, 0x00}, // 1
|
|
{0x00, 0x20}, // 2
|
|
{0x00, 0x10}, // 3
|
|
{0x00, 0x08}, // 4
|
|
{0x08, 0x00} // 5
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief hcs12ss59t_set_progress Set the progress bar value
|
|
* @param top Top progress bar value. 0 - HCS12SS59T_NUMDIGITS * 5
|
|
* @param bottom Bottom progress bar value. 0 - HCS12SS59T_NUMDIGITS * 5
|
|
*/
|
|
void hcs12ss59t_set_progress_peak(uint8_t top, uint8_t bottom,
|
|
uint8_t peak_top, uint8_t peak_bottom)
|
|
{
|
|
char charconf[HCS12SS59T_NUMDIGITS * 2];
|
|
int full;
|
|
int last;
|
|
char *ptr;
|
|
int row;
|
|
|
|
// Sanitize input
|
|
if (top > HCS12SS59T_NUMDIGITS * 5)
|
|
top = HCS12SS59T_NUMDIGITS * 5;
|
|
if (bottom > HCS12SS59T_NUMDIGITS * 5)
|
|
bottom = HCS12SS59T_NUMDIGITS * 5;
|
|
if (peak_top > HCS12SS59T_NUMDIGITS * 5)
|
|
peak_top = HCS12SS59T_NUMDIGITS * 5;
|
|
if (peak_bottom > HCS12SS59T_NUMDIGITS * 5)
|
|
peak_bottom = HCS12SS59T_NUMDIGITS * 5;
|
|
|
|
// Clear memory
|
|
for (ptr = charconf; ptr < charconf + HCS12SS59T_NUMDIGITS * 2; ++ptr) {
|
|
*ptr = 0;
|
|
}
|
|
|
|
// Calculate ticks
|
|
if (peak_top != 0) {
|
|
peak_top--;
|
|
ptr = charconf + ((peak_top / 5) * 2);
|
|
*(ptr++) |= hcs12ss59t_tick_styles[0][peak_top % 5][0];
|
|
*ptr |= hcs12ss59t_tick_styles[0][peak_top % 5][1];
|
|
}
|
|
if (peak_bottom != 0) {
|
|
peak_bottom--;
|
|
ptr = charconf + ((peak_bottom / 5) * 2);
|
|
*(ptr++) |= hcs12ss59t_tick_styles[1][peak_bottom % 5][0];
|
|
*ptr |= hcs12ss59t_tick_styles[1][peak_bottom % 5][1];
|
|
}
|
|
|
|
// Calculate top memory
|
|
for (row = 0; row < 2; ++row) {
|
|
if (row == 0) {
|
|
full = top / 5;
|
|
last = top % 5;
|
|
} else {
|
|
full = bottom / 5;
|
|
last = bottom % 5;
|
|
}
|
|
for (ptr = charconf; ptr < charconf + full * 2; ++ptr) {
|
|
*(ptr++) |= hcs12ss59t_bar_styles[row][0][0];
|
|
*ptr |= hcs12ss59t_bar_styles[row][0][1];
|
|
}
|
|
if (last != 0) {
|
|
*(ptr++) |= hcs12ss59t_bar_styles[row][last][0];
|
|
*ptr |= hcs12ss59t_bar_styles[row][last][1];
|
|
}
|
|
}
|
|
|
|
hcs12ss59t_set_character(0, charconf, HCS12SS59T_NUMDIGITS);
|
|
}
|
|
|
|
/**
|
|
* @brief hcs12ss59t_en_progress Prepare display for progress bar mode.
|
|
*/
|
|
void hcs12ss59t_en_progress()
|
|
{
|
|
hcs12ss59t_set_buffer("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B");
|
|
}
|