Fridge.c
Jump to navigation
Jump to search
/* fridge.g send text and images on a Fridge Magnet display * * Copyright 2013 Renzo Davoli Bologna - Italy * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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. * see <http://www.gnu.org/licenses/>. */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <poll.h> #define DISPLAYNODE 1 /* baudrate settings are defined in <asm/termbits.h>, which is included by <termios.h> */ #define BAUDRATE B57600 #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 const char font[][6] = { {0x00,0x00,0x00,0x00,0x00,0x00}, // SPACE {0x00,0x00,0x00,0x4F,0x00,0x00}, // ! {0x00,0x00,0x07,0x00,0x07,0x00}, // " {0x00,0x14,0x7F,0x14,0x7F,0x14}, // # {0x00,0x24,0x2A,0x7F,0x2A,0x12}, // $ {0x00,0x23,0x13,0x08,0x64,0x62}, // % {0x00,0x36,0x49,0x55,0x22,0x50}, // & {0x00,0x00,0x05,0x03,0x00,0x00}, // ' {0x00,0x00,0x1C,0x22,0x41,0x00}, // ( {0x00,0x00,0x41,0x22,0x1C,0x00}, // ) {0x00,0x14,0x08,0x3E,0x08,0x14}, // * {0x00,0x08,0x08,0x3E,0x08,0x08}, // + {0x00,0x00,0x50,0x30,0x00,0x00}, // , {0x00,0x08,0x08,0x08,0x08,0x08}, // - {0x00,0x00,0x60,0x60,0x00,0x00}, // . {0x00,0x20,0x10,0x08,0x04,0x02}, // / {0x00,0x3E,0x51,0x49,0x45,0x3E}, // 0 {0x00,0x00,0x42,0x7F,0x40,0x00}, // 1 {0x00,0x42,0x61,0x51,0x49,0x46}, // 2 {0x00,0x21,0x41,0x45,0x4B,0x31}, // 3 {0x00,0x18,0x14,0x12,0x7F,0x10}, // 4 {0x00,0x27,0x45,0x45,0x45,0x39}, // 5 {0x00,0x3C,0x4A,0x49,0x49,0x30}, // 6 {0x00,0x01,0x71,0x09,0x05,0x03}, // 7 {0x00,0x36,0x49,0x49,0x49,0x36}, // 8 {0x00,0x06,0x49,0x49,0x29,0x1E}, // 9 {0x00,0x36,0x36,0x00,0x00,0x00}, // : {0x00,0x56,0x36,0x00,0x00,0x00}, // ; {0x00,0x08,0x14,0x22,0x41,0x00}, // < {0x00,0x14,0x14,0x14,0x14,0x14}, // = {0x00,0x00,0x41,0x22,0x14,0x08}, // > {0x00,0x02,0x01,0x51,0x09,0x06}, // ? {0x00,0x30,0x49,0x79,0x41,0x3E}, // @ {0x00,0x7E,0x11,0x11,0x11,0x7E}, // A {0x00,0x7F,0x49,0x49,0x49,0x36}, // B {0x00,0x3E,0x41,0x41,0x41,0x22}, // C {0x00,0x7F,0x41,0x41,0x22,0x1C}, // D {0x00,0x7F,0x49,0x49,0x49,0x41}, // E {0x00,0x7F,0x09,0x09,0x09,0x01}, // F {0x00,0x3E,0x41,0x49,0x49,0x7A}, // G {0x00,0x7F,0x08,0x08,0x08,0x7F}, // H {0x00,0x00,0x41,0x7F,0x41,0x00}, // I {0x00,0x20,0x40,0x41,0x3F,0x01}, // J {0x00,0x7F,0x08,0x14,0x22,0x41}, // K {0x00,0x7F,0x40,0x40,0x40,0x40}, // L {0x00,0x7F,0x02,0x0C,0x02,0x7F}, // M {0x00,0x7F,0x04,0x08,0x10,0x7F}, // N {0x00,0x3E,0x41,0x41,0x41,0x3E}, // O {0x00,0x7F,0x09,0x09,0x09,0x06}, // P {0x00,0x3E,0x41,0x51,0x21,0x5E}, // Q {0x00,0x7F,0x09,0x19,0x29,0x46}, // R {0x00,0x46,0x49,0x49,0x49,0x31}, // S {0x00,0x01,0x01,0x7F,0x01,0x01}, // T {0x00,0x3F,0x40,0x40,0x40,0x3F}, // U {0x00,0x1F,0x20,0x40,0x20,0x1F}, // V {0x00,0x3F,0x40,0x30,0x40,0x3F}, // W {0x00,0x63,0x14,0x08,0x14,0x63}, // X {0x00,0x07,0x08,0x70,0x08,0x07}, // Y {0x00,0x61,0x51,0x49,0x45,0x43}, // Z {0x00,0x00,0x7F,0x41,0x41,0x00}, // [ {0x00,0x02,0x04,0x08,0x10,0x20}, // backslash {0x00,0x00,0x41,0x41,0x7F,0x00}, // ] {0x00,0x04,0x02,0x01,0x02,0x04}, // ^ {0x00,0x40,0x40,0x40,0x40,0x40}, // _ {0x00,0x00,0x01,0x02,0x04,0x00}, // ` {0x00,0x20,0x54,0x54,0x54,0x78}, // a {0x00,0x7F,0x50,0x48,0x48,0x30}, // b {0x00,0x38,0x44,0x44,0x44,0x20}, // c {0x00,0x38,0x44,0x44,0x48,0x7F}, // d {0x00,0x38,0x54,0x54,0x54,0x18}, // e {0x00,0x08,0x7E,0x09,0x01,0x02}, // f {0x00,0x0C,0x52,0x52,0x52,0x3E}, // g {0x00,0x7F,0x08,0x04,0x04,0x78}, // h {0x00,0x00,0x44,0x7D,0x40,0x00}, // i {0x00,0x20,0x40,0x44,0x3D,0x00}, // j {0x00,0x7F,0x10,0x28,0x44,0x00}, // k {0x00,0x00,0x41,0x7F,0x40,0x00}, // l {0x00,0x78,0x04,0x58,0x04,0x78}, // m {0x00,0x7C,0x08,0x04,0x04,0x78}, // n {0x00,0x38,0x44,0x44,0x44,0x38}, // o {0x00,0x7C,0x14,0x14,0x14,0x08}, // p {0x00,0x08,0x14,0x14,0x18,0x7C}, // q {0x00,0x7C,0x08,0x04,0x04,0x08}, // r {0x00,0x48,0x54,0x54,0x54,0x20}, // s {0x00,0x04,0x3F,0x44,0x40,0x20}, // t {0x00,0x3C,0x40,0x40,0x20,0x7C}, // u {0x00,0x1C,0x20,0x40,0x20,0x1C}, // v {0x00,0x3C,0x40,0x30,0x40,0x3C}, // w {0x00,0x44,0x28,0x10,0x28,0x44}, // x {0x00,0x0C,0x50,0x50,0x50,0x3C}, // y {0x00,0x44,0x64,0x54,0x4C,0x44}, // z {0x00,0x00,0x08,0x36,0x41,0x00}, // { {0x00,0x00,0x00,0x7F,0x00,0x00}, // | {0x00,0x00,0x41,0x36,0x08,0x00}, // } {0x00,0x0C,0x02,0x0C,0x10,0x0C}, // ~ {0x00,0x00,0x00,0x00,0x00,0x00} }; unsigned char screen[176][33]; void buildgraphic(void) { static int status=0; unsigned char *s= &screen[0][0]; unsigned char *base=s; int num=0; int c; while((c=getchar()) != EOF) { switch (status) { case 0: if (c=='{') status = 1; break; case 1: if (c=='0') { status = 8; break; } if (c>='1' && c <= '9') status=10; else break; case 10: if (c>='0' && c <= '9') num = (num * 10) | (c - '0'); else if (c==',') { *(s++) = num; num=0; status=1; if (s - base >= 5808) return; } else if (c=='}') { *(s++) = num; num=0; status=1; return; } break; case 8: if (c=='x') status = 16; else if (c>='0' && c <= '7') num = (num << 3) | (c - '0'); else if (c==',') { *(s++) = num; num=0; status=1; if (s - base >= 5808) return; } else if (c=='}') { *(s++) = num; num=0; status=1; return; } break; case 16: if (c>='0' && c <= '9') num = (num << 4) | (c - '0'); else if (c>='a' && c <= 'f') num = (num << 4) | (c + 10 - 'a'); else if (c>='A' && c <= 'F') num = (num << 4) | (c + 10 - 'A'); else if (c==',') { *(s++) = num; num=0; status=1; if (s - base >= 5808) return; } else if (c=='}') { *(s++) = num; num=0; status=1; return; } } } } void buildscreen(void) { int i; char buf[4096]; for (i=0;i<22;i++) { int len; if (fgets(buf,4096,stdin) == NULL) return; if (buf[0] == '\n') return; len=strlen(buf); if (len>44) len=44; int j; for (j=0; j<len; j++) { int ch=buf[j]; if (ch >= ' ' && ch <= '~') { int k; ch-=' '; for (k=0; k<6; k++) { int h; for (h=0; h<8; h++) { int bit=((font[ch][k]&(1<<h))!=0); if (bit) { int posx=j*6+k; int posy=i*8+h; screen[posy][posx>>3]|= 1<<(posx&0x7); } } } } } } } void sendit(int fd) { char buf[4096]; int i,res; for (i=0; i<176; i++) { int j; FILE *f=fmemopen(buf,sizeof(buf),"w"); fprintf(f,"%d,",i); for (j=0; j<33; j++) fprintf(f,"%d,",screen[i][j]); fprintf(f,"%ds\n",DISPLAYNODE); fclose(f); write(fd,buf,strlen(buf)); res = read(fd,buf,255); buf[res]=0; /* set end of string, so we can printf */ //printf(":%s:%d\n", buf, res); res = read(fd,buf,255); buf[res]=0; /* set end of string, so we can printf */ //printf(":%s:%d\n", buf, res); } } int main(int argc, char*argv[]) { int fd,c; struct termios oldtio,newtio; struct pollfd pfd[]={{0,POLLIN,0}}; if (argc > 2 && argv[2][0] == 'g') buildgraphic(); else buildscreen(); fd = open(argv[1], O_RDWR | O_NOCTTY ); if (fd <0) {perror(argv[1]); exit(-1); } pfd[0].fd=fd; tcgetattr(fd,&oldtio); bzero(&newtio, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = ICANON; newtio.c_cc[VINTR] = 0; /* Ctrl-c */ newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */ newtio.c_cc[VERASE] = 0; /* del */ newtio.c_cc[VKILL] = 0; /* @ */ newtio.c_cc[VEOF] = 4; /* Ctrl-d */ newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */ newtio.c_cc[VSWTC] = 0; /* '\0' */ newtio.c_cc[VSTART] = 0; /* Ctrl-q */ newtio.c_cc[VSTOP] = 0; /* Ctrl-s */ newtio.c_cc[VSUSP] = 0; /* Ctrl-z */ newtio.c_cc[VEOL] = 0; /* '\0' */ newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */ newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */ newtio.c_cc[VWERASE] = 0; /* Ctrl-w */ newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */ newtio.c_cc[VEOL2] = 0; /* '\0' */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); sleep(1); sendit(fd); sleep(1); sendit(fd); /* restore the old port settings */ tcsetattr(fd,TCSANOW,&oldtio); }