zzz
Revision 0:530fa614d79a, committed 2020-08-26
- Comitter:
- mauuuuul
- Date:
- Wed Aug 26 19:45:12 2020 +0000
- Commit message:
- zzzzzzzz
Changed in this revision
Noritake.cpp | Show annotated file Show diff for this revision Revisions of this file |
Noritake.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Noritake.cpp Wed Aug 26 19:45:12 2020 +0000 @@ -0,0 +1,558 @@ +#include "mbed.h" +#include "Noritake.h" +#include <string.h> + +Noritake::Noritake(PinName tx, PinName rx):VFDSerial(tx, rx) +{ + VFDSerial.baud(NORITAKE_BAUD_DEF); +} + +Noritake::~Noritake() +{ + +} + +void Noritake::writePort(uint8_t data) +{ + VFDSerial.putc(data); +} +void Noritake::hardReset() +{ + VFDSerial.putc(0x0c); + wait_ms(200); + VFDSerial.putc(0x1f); + VFDSerial.putc(0x24); + VFDSerial.putc(0x00); + VFDSerial.putc(0x00); + VFDSerial.putc(0x00); + VFDSerial.putc(0x00); +} + +void Noritake::GU7000_back() { + command(0x08); +} + +void Noritake::GU7000_forward() { + command(0x09); +} + +void Noritake::GU7000_lineFeed() { + command(0x0a); +} + +void Noritake::GU7000_home() { + command(0x0b); +} + +void Noritake::GU7000_carriageReturn() { + command(0x0d); +} + +void Noritake::GU7000_setCursor(unsigned x, unsigned y) { + command(0x1f); + command('$'); + command_xy(x, y); +} + +void Noritake::GU7000_clearScreen() { + command(0x0c); +} + +void Noritake::GU7000_cursorOn() { + command(0x1f, 'C', 1); +} + +void Noritake::GU7000_cursorOff() { + command(0x1f, 'C', 0); +} + +void Noritake::GU7000_init() { + wait_us(NORITAKE_VFD_RESET_DELAY); + command(0x1b); + command('@'); +} + +void Noritake::GU7000_reset() { + hardReset(); +} + +void Noritake::GU7000_useMultibyteChars(bool enable) { + #if (NORITAKE_VFD_MODEL_CLASS-7000)/100==9 || (NORITAKE_VFD_MODEL_CLASS-7000)/100==1 + us_command('g', 0x02); + command(enable); + #endif +} + +void Noritake::GU7000_setMultibyteCharset(uint8_t code) { + #if (NORITAKE_VFD_MODEL_CLASS-7000)/100==9 || (NORITAKE_VFD_MODEL_CLASS-7000)/100==1 + us_command('g', 0x0f); + command(code); + #endif +} + +void Noritake::GU7000_useCustomChars(bool enable) { + command(0x1b, '%', enable); +} + +static inline uint8_t getColumn(const uint8_t *src, int col) { + uint8_t out = 0; + for (int i=0; i<8; i++) + if (src[i] & (1<<(4-col))) out += 1<<(7-i); + return out; +} + +void Noritake::GU7000_defineCustomChar(uint8_t code, FontFormat format, const uint8_t *data) { + command(0x1b, '&', 0x01); + command(code); + command(code); + + switch (format) { + case CUUFormat: + command(5); + for (uint8_t i=0; i<5; i++) + command(getColumn(data, i)); + break; + + case GU70005x7Format: + command(5); + print((const char*)data, 5); + break; + case GU70007x8Format: + command(7); + print((const char*)data, 7); + break; + } +} + +void Noritake::GU7000_deleteCustomChar(uint8_t code) { + command(0x01b, '?', 0x01); + command(code); +} + +void Noritake::GU7000_setAsciiVariant(AsciiVariant code) { + command(0x1b, 'R', code); +} + +void Noritake::GU7000_setCharset(Charset code) { + command(0x1b, 't', code); +} + +void Noritake::GU7000_setScrollMode(ScrollMode mode) { + command(0x1f); + command(mode); +} + +void Noritake::GU7000_setHorizScrollSpeed(uint8_t speed) { + command(0x1f, 's', speed); +} + +void Noritake::GU7000_invertOff() { + command(0x1f, 'r', 0); +} + +void Noritake::GU7000_invertOn() { + command(0x1f, 'r', 1); +} + +void Noritake::GU7000_setCompositionMode(CompositionMode mode) { + command(0x1f, 'w', mode); +} + +void Noritake::GU7000_setScreenBrightness(unsigned level) { + if (level == 0) + GU7000_displayOff(); + else if (level <= 100) { + GU7000_displayOn(); + command(0x1f, 'X', (level*10 + 120)/125); + } +} + +void Noritake::GU7000_wait(uint8_t time) { + us_command('a', 0x01); + command(time); +} + +void Noritake::GU7000_scrollScreen(unsigned x, unsigned y, unsigned times, uint8_t speed) { + unsigned pos = (x*NORITAKE_VFD_LINES)+(y/8); + us_command('a', 0x10); + command(pos); + command(pos>>8); + command(times); + command(times>>8); + command(speed); +} + +void Noritake::GU7000_blinkScreen() { + us_command('a', 0x11); + command(0); + command(0); + command(0); + command(0); +} + +void Noritake::GU7000_blinkScreen(bool enable, bool reverse, uint8_t onTime, uint8_t offTime, uint8_t times) { + us_command('a', 0x11); + command(enable? (reverse? 2: 1): 0); + command(onTime); + command(offTime); + command(times); +} + +void Noritake::GU7000_displayOff() { + us_command('a', 0x40); + command(0); +} + +void Noritake::GU7000_displayOn() { + us_command('a', 0x40); + command(0x01); +} + +void Noritake::GU7000_screenSaver(ScreenSaver mode) { + us_command('a', 0x40); + command(mode); +} + +void Noritake::GU7000_setFontStyle(bool proportional, bool evenSpacing) { + us_command('g', 0x03); + command(proportional*2 + evenSpacing); +} + +void Noritake::GU7000_setFontSize(uint8_t x, uint8_t y, bool tall) { + if (x<=4 && y<=4) { + us_command('g', 0x40); + command(x); + command(y); + #if (NORITAKE_VFD_MODEL_CLASS-7000)/100==9 || (NORITAKE_VFD_MODEL_CLASS-7000)/100==1 + us_command('g', 0x01); + command(tall+1); + #endif + } +} + +void Noritake::GU7000_selectWindow(uint8_t window) { + if (window <= 4) + command(0x10 + window); +} + +void Noritake::GU7000_defineWindow(uint8_t window, unsigned x, unsigned y, unsigned width, unsigned height) { + us_command('w', 0x02); + command(window); + command(0x01); + command_xy(x, y); + command_xy(width, height); +} + +void Noritake::GU7000_deleteWindow(uint8_t window) { + us_command('w', 0x02); + command(window); + command(0); + command_xy(0, 0); + command_xy(0, 0); +} + +void Noritake::GU7000_joinScreens() { + us_command('w', 0x10); + command(0x01); +} + +void Noritake::GU7000_separateScreens() { + us_command('w', 0x10); + command(0); +} + +void Noritake::print(char c) { + command(c); +} + +void Noritake::print(const char *str, ...) { + while (*str) + writePort(*str++); +} + +void Noritake::print(const char *buffer, size_t size) { + while (size--) + print(*buffer++); +} + +void Noritake::print(long number, uint8_t base) { + if (number < 0) { + print('-'); + number = -number; + } + printNumber(number, base); +} + +void Noritake::print(int number, uint8_t base) { + print((long)number, base); +} + +void Noritake::print(unsigned long number, uint8_t base) { + printNumber(number, base); +} + +void Noritake::print(unsigned number, uint8_t base) { + print((unsigned long)number, base); +} + +void Noritake::printat(unsigned x, uint8_t y, const char *str) +{ + GU7000_setCursor(x, y); + print(str); +} + +void Noritake::crlf() { + GU7000_carriageReturn(); + GU7000_lineFeed(); +} + +void Noritake::println(char c) { + print(c); + crlf(); +} + +void Noritake::println(const char *str) { + print(str); + crlf(); +} + +void Noritake::println(const char *buffer, size_t size) { + print(buffer, size); + crlf(); +} + +void Noritake::println(long number, uint8_t base) { + print(number, base); + crlf(); +} + +void Noritake::println(int number, uint8_t base) { + println((long) number, base); +} + +void Noritake::println(unsigned long number, uint8_t base) { + print(number, base); + crlf(); +} + +void Noritake::println(unsigned number, uint8_t base) { + println((unsigned long) number, base); +} + +void Noritake::printNumber(unsigned long number, uint8_t base) { + if (number/base) + printNumber(number/base, base); + number %= base; + print(number + (number < 10? '0': 'A' - 10)); +} + +void Noritake::GU7000_setBacklightColor(uint8_t r, uint8_t g, uint8_t b) { + #if NORITAKE_VFD_MODEL_CLASS==7040 + command(0x1f, 'L', 0x10); + command(b & 0xf0); + command(g & 0xf0); + command(r & 0xf0); + #endif +} + +void Noritake::GU7000_setBacklightColor(unsigned rgb) { + GU7000_setBacklightColor((rgb>>8 & 0x0f)*16, (rgb>>4 & 0x0f)*16, (rgb & 0x0f)*16); +} + +void Noritake::GU7000_drawImage(unsigned width, uint8_t height, const uint8_t *data) { + if (height > NORITAKE_VFD_HEIGHT) return; + us_command('f', 0x11); + command_xy(width, height); + command((uint8_t) 1); + for (unsigned i = 0; i<(height/8)*width; i++) + command(data[i]); +} + +void Noritake::GU7000_drawFROMImage(unsigned long address, uint8_t srcHeight, unsigned width, uint8_t height) { + #if (NORITAKE_VFD_MODEL_CLASS-7000)/100==9 || (NORITAKE_VFD_MODEL_CLASS-7000)/100==1 + if (height > NORITAKE_VFD_HEIGHT) return; + us_command('f', 0x10); + command(0x01); + command(address); + command(address>>8); + command(address>>16); + command(srcHeight/8); + command((srcHeight/8)>>8); + command_xy(width, height); + command((uint8_t) 1); + #endif +} + +static unsigned min(unsigned x, unsigned y) { return x<y? x: y; } + +void Noritake::GU7000_fillRect(unsigned x0, unsigned y0, unsigned x1, unsigned y1, bool on) { + x0 = min(NORITAKE_VFD_WIDTH, x0); + x1 = min(NORITAKE_VFD_WIDTH, x1); + y0 = min(NORITAKE_VFD_HEIGHT, y0); + y1 = min(NORITAKE_VFD_HEIGHT, y1); + if (y1<=y0 || x1<=x0) return; + uint8_t bufw = 8, bufh = (y1-y0+7)/8*8; + uint8_t *buf = (uint8_t*) malloc(bufh/8 * bufw); + for (unsigned x = 0; x < x1-x0; x += bufw) { + uint8_t part = (x + bufw < x1-x0)? bufw: (x1-x0) - x; + memset(buf, 0, bufh/8 * bufw); + if (on) + for (uint8_t col = 0; col < part; col++) { + for (uint8_t py = y0 % 8; py < y0 % 8 + min(y1-y0, 8); py++) + buf[col*bufh/8] |= 1 << (7-py); + for (uint8_t row = (y0+7)/8; row < y1/8; row++) + buf[row - y0/8 + col*bufh/8] = 0xff; + if (y0/8 != y1/8) + for (uint8_t py = 0; py < y1 % 8; py++) + buf[(y1-y0)/8 + col*bufh/8] |= 1 << (7-py); + } + GU7000_setCursor(x + x0, y0); + GU7000_drawImage(bufw, bufh, buf); + } +} + +void Noritake::command(uint8_t data) { +// writePort(data); + VFDSerial.putc(data); +} +void Noritake::command_xy(unsigned x, unsigned y) { + command(x); + command(x>>8); + y /= 8; + command(y); + command(y>>8); +} +void Noritake::command_xy1(unsigned x, unsigned y) { + command(x); + command(x>>8); + command(y); + command(y>>8); +} + +void Noritake::us_command(uint8_t group, uint8_t cmd) { + command(0x1f); + command(0x28); + command(group); + command(cmd); +} + +void Noritake::command(uint8_t prefix, uint8_t group, uint8_t cmd) { + command(prefix); + command(group); + command(cmd); +} + +void Noritake::print(unsigned x, uint8_t y, const char *buffer, uint8_t len) { + #if NORITAKE_VFD_GENERATION == 'B' + us_command('d', 0x30); + command_xy1(x, y); + command(0); + command(len); + while (len--) + command(*buffer++); + #endif +} + +void Noritake::print(unsigned x, uint8_t y, const char *str) { + #if NORITAKE_VFD_GENERATION == 'B' + print(x, y, str, strlen(str)); + #endif +} +void Noritake::print(unsigned x, uint8_t y, char c) { + #if NORITAKE_VFD_GENERATION == 'B' + print(x, y, &c, 1); + #endif +} +void Noritake::print(unsigned x, uint8_t y, int number, uint8_t base) { + #if NORITAKE_VFD_GENERATION == 'B' + if (number < 0) { + print(x, y, '-'); + print(-1, y, (unsigned)-number, base); + } else + print(x, y, (unsigned)number, base); + #endif +} +void Noritake::print(unsigned x, uint8_t y, unsigned number, uint8_t base) { + #if NORITAKE_VFD_GENERATION == 'B' + char buf[16], *p = buf + sizeof buf; + do + *--p = number % base + (number % base < 10? '0': 'A' - 10); + while (number /= base); + print(x, y, p, buf + sizeof buf - p); + #endif +} +void Noritake::GU7000_drawImage(unsigned x, uint8_t y, unsigned width, uint8_t height, const char *data) { + #if NORITAKE_VFD_GENERATION == 'B' + us_command('d', 0x21); + command_xy1(x, y); + command_xy1(width, height); + command(0x01); + for (unsigned i = 0; i<(height/8)*width; i++) + command(data[i]); + #endif +} +void Noritake::GU7000_drawImage(unsigned x, uint8_t y, ImageMemoryArea area, unsigned long address, uint8_t srcHeight, unsigned width, uint8_t height, unsigned offsetx, unsigned offsety) { + #if NORITAKE_VFD_GENERATION == 'B' + if (height > NORITAKE_VFD_HEIGHT) return; + us_command('d', 0x20); + command_xy1(x, y); + command(area); + command(address); + command(address>>8); + command(address>>16); + command(srcHeight/8); + command(srcHeight/8>>8); + command_xy1(offsetx, offsety); + command_xy1(width, height); + command(0x01); + #endif +} + +void Noritake::GU7000_drawImage(unsigned x, uint8_t y, ImageMemoryArea area, unsigned long address, unsigned width, uint8_t height) { + #if NORITAKE_VFD_GENERATION == 'B' + GU7000_drawImage(x, y, area, address, (height + 7) & ~7, width, height, 0, 0); + #endif +} + +void Noritake::print_p(const char *str) { + while (pgm_read_byte(str)) + writePort(pgm_read_byte(str++)); +} +void Noritake::print_p(unsigned x, uint8_t y, const char *buffer, uint8_t len) { + #if NORITAKE_VFD_GENERATION == 'B' + us_command('d', 0x30); + command_xy1(x, y); + command(0); + command(len); + while (len--) + command(pgm_read_byte(buffer++)); + #endif +} + +void Noritake::print_p(unsigned x, uint8_t y, const char *str) { + #if NORITAKE_VFD_GENERATION == 'B' + const char *end = str; + while (pgm_read_byte(end)) end++; + print_p(x, y, str, end - str); + #endif +} + +void Noritake::GU7000_drawImage_p(unsigned width, uint8_t height, const uint8_t *data) { + if (height > NORITAKE_VFD_HEIGHT) return; + us_command('f', 0x11); + command_xy(width, height); + command((uint8_t) 1); + for (unsigned i = 0; i<(height/8)*width; i++) + command(pgm_read_byte(data+i)); +} + +void Noritake::GU7000_drawImage_p(unsigned x, uint8_t y, unsigned width, uint8_t height, const uint8_t *data) { + #if NORITAKE_VFD_GENERATION == 'B' + us_command('d', 0x21); + command_xy1(x, y); + command_xy1(width, height); + command(0x01); + for (unsigned i = 0; i<(height/8)*width; i++) + command(pgm_read_byte(data+i)); + #endif +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Noritake.h Wed Aug 26 19:45:12 2020 +0000 @@ -0,0 +1,185 @@ +#ifndef NORITAKE_H +#define NORITAKE_H + +#define NORITAKE_VFD_MODEL_CLASS 7003 +#define NORITAKE_VFD_WIDTH 128 +#define NORITAKE_VFD_HEIGHT 64 +#define NORITAKE_VFD_LINES (NORITAKE_VFD_HEIGHT/8) +#define NORITAKE_VFD_RESET_DELAY 500 +#define NORITAKE_BAUD_DEF 38400 +#define pgm_read_byte(p) (*(uint8_t*)p) + +#include "SoftSerial.h" + +enum ImageMemoryArea { + FlashImageArea = 1, + ScreenImageArea = 2 +}; + +enum ScrollMode { + WrappingMode = 1, + VertScrollMode = 2, + HorizScrollMode = 3 +}; + +enum CompositionMode { + NormalCompositionMode = 0, + OrCompositionMode = 1, + AndCompositionMode = 2, + XorCompositionMode = 3 +}; + +enum ScreenSaver { + AllDotsOffSaver = 2, + AllDotsOnSaver = 3, + InvertSaver = 4 +}; + +enum LEDColor { + NoLight = 0x000, + BlueLight = 0x00f, + GreenLight = 0x0f0, + CyanLight = 0x0ff, + RedLight = 0xf00, + MagentaLight = 0xf0f, + SmokeLight = 0xfff +}; + +enum FontFormat { + GU70005x7Format =0, + GU70007x8Format =1, + CUUFormat = 2, + LCDFormat = CUUFormat +}; + +enum AsciiVariant { + AmericaAscii = 0, + FranceAscii = 1, + GermanyAscii = 2, + EnglandAscii = 3, + Denmark1Ascii = 4, + SweedenAscii = 5, + ItalyAscii = 6, + Spain1Ascii = 7, + JapanAscii = 8, + NorwayAscii = 9, + Denmark2Ascii = 10, + Spain2Ascii = 11, + LatinAmericaAscii = 12, + KoreaAscii = 13 +}; + +enum Charset { + CP437 = 0, EuroStdCharset = CP437, + Katakana = 1, + CP850 = 2, MultilingualCharset = CP850, + CP860 = 3, PortugeseCharset = CP860, + CP863 = 4, CanadianFrenchCharset = CP863, + CP865 = 5, NordicCharset = CP865, + CP1252 = 0x10, + CP866 = 0x11, Cyrillic2Charset = CP866, + CP852 = 0x12, Latin2Charset = CP852, + CP858 = 0x13 +}; + +class Noritake { + + void initialState(); + void printNumber(unsigned long number, uint8_t base); + void printNumber(unsigned x, uint8_t y, unsigned long number, uint8_t base); + void command(uint8_t data); + void us_command(uint8_t group, uint8_t cmd); + void command(uint8_t prefix, uint8_t group, uint8_t cmd); + void command_xy(unsigned x, unsigned y); + void command_xy1(unsigned x, unsigned y); + void crlf(); + +public: + + void GU7000_back(); + void GU7000_forward(); + void GU7000_lineFeed(); + void GU7000_home(); + void GU7000_carriageReturn(); + void GU7000_setCursor(unsigned x, unsigned y); + void GU7000_clearScreen(); + void GU7000_cursorOn(); + void GU7000_cursorOff(); + void GU7000_init(); + void GU7000_reset(); + void GU7000_useMultibyteChars(bool enable); + void GU7000_setMultibyteCharset(uint8_t code); + void GU7000_useCustomChars(bool enable); + void GU7000_defineCustomChar(uint8_t code, FontFormat format, const uint8_t *data); + void GU7000_deleteCustomChar(uint8_t code); + void GU7000_setAsciiVariant(AsciiVariant code); + void GU7000_setCharset(Charset code); + void GU7000_setScrollMode(ScrollMode mode); + void GU7000_setHorizScrollSpeed(uint8_t speed); + void GU7000_invertOn(); + void GU7000_invertOff(); + void GU7000_setCompositionMode(CompositionMode mode); + void GU7000_setScreenBrightness(unsigned level); + void GU7000_wait(uint8_t time); + void GU7000_scrollScreen(unsigned x, unsigned y, unsigned count, uint8_t speed); + void GU7000_blinkScreen(); + void GU7000_blinkScreen(bool enable, bool reverse, uint8_t on, uint8_t off, uint8_t times); + void GU7000_displayOn(); + void GU7000_displayOff(); + void GU7000_screenSaver(ScreenSaver mode); + void GU7000_drawImage(unsigned width, uint8_t height, const uint8_t *data); + void GU7000_drawFROMImage(unsigned long address, uint8_t srcHeight, unsigned width, uint8_t height); + void GU7000_setFontStyle(bool proportional, bool evenSpacing); + void GU7000_setFontSize(uint8_t x, uint8_t y, bool tall); + void GU7000_selectWindow(uint8_t window); + void GU7000_defineWindow(uint8_t window, unsigned x, unsigned y, unsigned width, unsigned height); + void GU7000_deleteWindow(uint8_t window); + void GU7000_joinScreens(); + void GU7000_separateScreens(); + void GU7000_setBacklightColor(uint8_t r, uint8_t g, uint8_t b); + void GU7000_setBacklightColor(unsigned rgb); + + void print(char c); + void print(const char *str, ...); + void print(const char *buffer, size_t size); + void print(int number, uint8_t base); + void print(unsigned number, uint8_t base); + void print(long number, uint8_t base); + void print(unsigned long number, uint8_t base); + void printat(unsigned x, uint8_t y, const char *str); + void println(char c); + void println(const char *str); + void println(const char *buffer, size_t size); + void println(int number, uint8_t base); + void println(unsigned number, uint8_t base); + void println(long number, uint8_t base); + void println(unsigned long number, uint8_t base); + + void GU7000_fillRect(unsigned x0, unsigned y0, unsigned x1, unsigned y1, bool on=true); + + void print(unsigned x, uint8_t y, char c); + void print(unsigned x, uint8_t y, const char *str); + void print(unsigned x, uint8_t y, const char *buffer, uint8_t len); + void print(unsigned x, uint8_t y, int number, uint8_t base); + void print(unsigned x, uint8_t y, unsigned number, uint8_t base); + void GU7000_drawImage(unsigned x, uint8_t y, unsigned width, uint8_t height, const char *data); + void GU7000_drawImage(unsigned x, uint8_t y, ImageMemoryArea area, unsigned long address, uint8_t srcHeight, unsigned width, uint8_t height, unsigned offsetx, unsigned offsety); + void GU7000_drawImage(unsigned x, uint8_t y, ImageMemoryArea area, unsigned long address, unsigned width, uint8_t height); + + void print_p(const char *str); + void print_p(unsigned x, uint8_t y, const char *str); + void print_p(unsigned x, uint8_t y, const char *buffer, uint8_t len); + void GU7000_drawImage_p(unsigned width, uint8_t height, const uint8_t *data); + void GU7000_drawImage_p(unsigned x, uint8_t y, unsigned width, uint8_t height, const uint8_t *data); + + Noritake(PinName tx, PinName rx); + virtual ~Noritake(); + +private: + SoftSerial VFDSerial; + void writePort(uint8_t data); + void hardReset(); +}; + + +#endif // NORITAKE_H \ No newline at end of file