# HG changeset patch # User Michiel Broek # Date 1449073001 -3600 # Node ID 6b80a37fdf8d3c1ff991df3d8abbdb917040ccbe # Parent 1193bd7d460fdebadb4e94914101713dfe153611 Added programming display CGRAM. Added display of characters from CGRAM. Changed prompts to allow free prompt strings. More code for the brewsystem unit editor. diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/brewco.c --- a/brewco/brewco.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/brewco.c Wed Dec 02 17:16:41 2015 +0100 @@ -48,6 +48,19 @@ #endif +/* + * CGRAM characters + */ +unsigned char degC[8] = { 0b01000, 0b10100, 0b01000, 0b00111, 0b01000, 0b01000, 0b01000, 0b00111 }; +unsigned char degF[8] = { 0b01000, 0b10100, 0b01000, 0b00111, 0b00100, 0b00110, 0b00100, 0b00100 }; +unsigned char SP_Symbol[8] = { 0b11100, 0b10000, 0b11100, 0b00111, 0b11101, 0b00111, 0b00100, 0b00100 }; +unsigned char PumpONOFF[8] = { 0b00000, 0b01110, 0b01010, 0b01110, 0b01000, 0b01000, 0b01000, 0b00000 }; +unsigned char RevPumpONOFF[8] = { 0b11111, 0b10001, 0b10101, 0b10001, 0b10111, 0b10111, 0b10111, 0b11111 }; +unsigned char HeatONOFF[8] = { 0b00000, 0b01010, 0b01010, 0b01110, 0b01110, 0b01010, 0b01010, 0b00000 }; +unsigned char RevHeatONOFF[8] = { 0b11111, 0b10101, 0b10101, 0b10001, 0b10001, 0b10101, 0b10101, 0b11111 }; +unsigned char Language[8] = { 0b11111, 0b00010, 0b01000, 0b11111, 0b00000, 0b10001, 0b10101, 0b11111 }; + + void help(void); void die(int); @@ -94,6 +107,22 @@ long t = 0; #endif + prompt(101, NULL); + + /* + * Define special characters in the display CGRAM + */ + if (Config.tempFormat == 'C') + slcdCharDef(slcdHandle, 1, degC); + else + slcdCharDef(slcdHandle, 1, degF); + slcdCharDef(slcdHandle, 2, SP_Symbol); + slcdCharDef(slcdHandle, 3, PumpONOFF); + slcdCharDef(slcdHandle, 4, RevPumpONOFF); + slcdCharDef(slcdHandle, 5, HeatONOFF); + slcdCharDef(slcdHandle, 6, RevHeatONOFF); + slcdCharDef(slcdHandle, 7, Language); + // if (lockprog((char *)"brewco")) { // syslog(LOG_NOTICE, "Can't lock"); // return 1; @@ -170,13 +199,12 @@ } } - prompt(101); if (! Config.units) { /* * No brewsystems defined, add the first */ - prompt(218); /* Add Brewsystem? */ - prompt(407); /* --- --- Ok --- */ + prompt(218, NULL); /* Add Brewsystem? */ + prompt(407, NULL); /* --- --- Ok --- */ do { key = keywait(); @@ -217,9 +245,10 @@ /* * Not running. */ - prompt(0); - prompt(101); - prompt(401); + prompt(0, NULL); + prompt(101, NULL); + prompt(300, (char *)"---\001-\002-\003-\004-\005-\006-\007----"); + prompt(401, NULL); key = keywait(); if (key == KEY_ENTER) setup(); @@ -233,9 +262,9 @@ if (debug) fprintf(stdout, (char *)"Out of loop\n"); - prompt(0); - prompt(101); - prompt(302); + prompt(0, NULL); + prompt(101, NULL); + prompt(302, NULL); /* * Stop units processing in a neat way @@ -249,7 +278,7 @@ */ usleep(1500000); - prompt(0); + prompt(0, NULL); // stopLCD(); if (sock != -1) { if (shutdown(sock, SHUT_RDWR)) { diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/brewco.h --- a/brewco/brewco.h Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/brewco.h Wed Dec 02 17:16:41 2015 +0100 @@ -83,6 +83,8 @@ #define MBSE_SS(x) (x)?(x):"(null)" + + /* * Sensor strcuture */ diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/prompt.c --- a/brewco/prompt.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/prompt.c Wed Dec 02 17:16:41 2015 +0100 @@ -32,7 +32,7 @@ -void prompt(int index) +void prompt(int index, char *text) { char message[81]; int line; @@ -48,7 +48,9 @@ piUnlock(LOCK_LCD); #endif return; - case 101: snprintf(message, Config.lcd_cols + 1, " Brewco %s ", VERSION); + case 100: snprintf(message, Config.lcd_cols + 1, text); + break; + case 101: snprintf(message, Config.lcd_cols + 1, " Brewco %s \007", VERSION); break; case 102: snprintf(message, Config.lcd_cols + 1, " SETUP MENU "); break; @@ -58,21 +60,33 @@ break; case 111: snprintf(message, Config.lcd_cols + 1, "AUTO --> Mash In "); break; - case 112: snprintf(message, Config.lcd_cols + 1, "AUTO --> Fitasi "); + case 112: snprintf(message, Config.lcd_cols + 1, "AUTO --> Phytase "); break; - case 113: snprintf(message, Config.lcd_cols + 1, "AUTO --> Glucanasi "); + case 113: snprintf(message, Config.lcd_cols + 1, "AUTO --> Glucanase "); break; - case 114: snprintf(message, Config.lcd_cols + 1, "AUTO --> Proteasi "); + case 114: snprintf(message, Config.lcd_cols + 1, "AUTO --> Protease "); break; - case 115: snprintf(message, Config.lcd_cols + 1, "AUTO --> B-amilasi "); + case 115: snprintf(message, Config.lcd_cols + 1, "AUTO --> \342-Amylase "); /* Beta */ break; - case 116: snprintf(message, Config.lcd_cols + 1, "AUTO --> A-amilasi 1"); + case 116: snprintf(message, Config.lcd_cols + 1, "AUTO --> \340-Amylase 1"); /* Alpha */ break; - case 117: snprintf(message, Config.lcd_cols + 1, "AUTO --> A-amilasi 2"); + case 117: snprintf(message, Config.lcd_cols + 1, "AUTO --> \340-Amylase 2"); break; case 118: snprintf(message, Config.lcd_cols + 1, "AUTO --> Mash Out "); break; - case 121: snprintf(message, Config.lcd_cols + 1, "AUTO --> Hop xx "); + case 119: snprintf(message, Config.lcd_cols + 1, "AUTO --> Boil "); + break; + case 120: snprintf(message, Config.lcd_cols + 1, "AUTO --> Cooling "); + break; + case 121: snprintf(message, Config.lcd_cols + 1, "AUTO --> Whirlpool "); + break; + case 122: snprintf(message, Config.lcd_cols + 1, "AUTO --> Hop xx "); + break; + case 131: snprintf(message, Config.lcd_cols + 1, " Edit brewsystem "); + break; + case 132: snprintf(message, Config.lcd_cols + 1, " Toggle Yes/No "); + break; + case 200: snprintf(message, Config.lcd_cols + 1, text); break; case 202: snprintf(message, Config.lcd_cols + 1, " Manage Recipes "); break; @@ -108,9 +122,13 @@ break; case 218: snprintf(message, Config.lcd_cols + 1, " Add Brewsystem? "); break; - case 301: snprintf(message, Config.lcd_cols + 1, " Finished "); + case 300: snprintf(message, Config.lcd_cols + 1, text); + break; + case 301: snprintf(message, Config.lcd_cols + 1, " Finished "); break; - case 302: snprintf(message, Config.lcd_cols + 1, " Shutting down "); + case 302: snprintf(message, Config.lcd_cols + 1, " Shutting down "); + break; + case 400: snprintf(message, Config.lcd_cols + 1, text); break; case 401: snprintf(message, Config.lcd_cols + 1, "--- MAN AUTO SETUP"); break; diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/prompt.h --- a/brewco/prompt.h Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/prompt.h Wed Dec 02 17:16:41 2015 +0100 @@ -1,6 +1,6 @@ #ifndef _PROMPT_H #define _PROMPT_H -void prompt(int); +void prompt(int, char *); #endif diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/setup.c --- a/brewco/setup.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/setup.c Wed Dec 02 17:16:41 2015 +0100 @@ -36,11 +36,166 @@ +int toggleYesNo(int value, char *text) +{ + int key, new = value; + char pmpt[81]; + + prompt(0, NULL); + prompt(132, NULL); + + for (;;) { + + snprintf(pmpt, Config.lcd_cols + 1, "%s: %s", text, new ? (char *)"Yes":(char *)"No "); + prompt(200, pmpt); + if (new) { + prompt(404, NULL); + } else { + prompt(402, NULL); + } + + key = keywait(); + if ((key == KEY_RETURN) || my_shutdown) + return value; + if ((key == KEY_UP) && new) + new = 0; + else if ((key == KEY_DOWN) && (new == 0)) + new = 1; + if (key == KEY_ENTER) + return new; + } +} + + + void editUnit(units_list *unit) { + int index = 1, key; + char pmpt[81]; + if (debug) fprintf(stdout, "Start edit brewsystem %d %s\n", unit->number, unit->uuid); + prompt(0, NULL); + + for (;;) { + + prompt(0, NULL); + prompt(131, NULL); + + if (index == 1) + prompt(402, NULL); + else if (index == 21) + prompt(404, NULL); + else + prompt(403, NULL); + + switch (index) { // 12345678901234567890 + case 1: snprintf(pmpt, Config.lcd_cols + 1, "Unit name:"); + prompt(200, pmpt); + snprintf(pmpt, Config.lcd_cols + 1, "%s", unit->name); + prompt(300, pmpt); + break; + case 2: snprintf(pmpt, Config.lcd_cols + 1, " HLT sensor setup"); + prompt(200, pmpt); + break; + case 3: snprintf(pmpt, Config.lcd_cols + 1, " HLT heater setup"); + prompt(200, pmpt); + break; + case 4: snprintf(pmpt, Config.lcd_cols + 1, " MLT sensor setup"); + prompt(200, pmpt); + break; + case 5: snprintf(pmpt, Config.lcd_cols + 1, " MLT heater setup"); + prompt(200, pmpt); + break; + case 6: snprintf(pmpt, Config.lcd_cols + 1, " MLT pump setup"); + prompt(200, pmpt); + break; + case 7: snprintf(pmpt, Config.lcd_cols + 1, "MLT heat b4 HLT: %s", unit->hlt_heater_mltfirst ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 8: snprintf(pmpt, Config.lcd_cols + 1, "Pump cycle: %2d mins", unit->pump_cycle); + prompt(200, pmpt); + break; + case 9: snprintf(pmpt, Config.lcd_cols + 1, "Pump rest : %2d mins", unit->pump_rest); + prompt(200, pmpt); + break; + case 10: snprintf(pmpt, Config.lcd_cols + 1, " Pump pre-mash: %s", unit->pump_premash ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 11: snprintf(pmpt, Config.lcd_cols + 1, " Pump on-mash: %s", unit->pump_onmash ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 12: snprintf(pmpt, Config.lcd_cols + 1, " Pump mashout: %s", unit->pump_mashout ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 13: snprintf(pmpt, Config.lcd_cols + 1, " Pump on-boil: %s", unit->pump_onboil ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 14: snprintf(pmpt, Config.lcd_cols + 1, " Pump stop: %3d\337C", unit->pump_stop); + prompt(200, pmpt); + break; + case 15: snprintf(pmpt, Config.lcd_cols + 1, " Skip Add: %s", unit->skip_add ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 16: snprintf(pmpt, Config.lcd_cols + 1, " Skip Remove: %s", unit->skip_remove ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 17: snprintf(pmpt, Config.lcd_cols + 1, " Skip Iodine: %s", unit->skip_iodine ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 18: snprintf(pmpt, Config.lcd_cols + 1, "Iodine time: %3d min", unit->iodine_time); + prompt(200, pmpt); + break; + case 19: snprintf(pmpt, Config.lcd_cols + 1, " Whirlpool: %s", unit->whirlpool ? (char *)"Yes":(char *)"No"); + prompt(200, pmpt); + break; + case 20: snprintf(pmpt, Config.lcd_cols + 1, " HLT PID setup"); + prompt(200, pmpt); + break; + case 21: snprintf(pmpt, Config.lcd_cols + 1, " MLT PID setup"); + prompt(200, pmpt); + break; + } + + key = keywait(); + if ((key == KEY_RETURN) || my_shutdown) + return; + + if ((key == KEY_UP) && (index > 1)) + index--; + if ((key == KEY_DOWN) && (index < 21)) + index++; + + if (key == KEY_ENTER) { + switch(index) { + case 7: unit->hlt_heater_mltfirst = toggleYesNo(unit->hlt_heater_mltfirst , (char *)"MLT heat b4 HLT"); + break; + } + } + // name + // hlt_sensor picklist + // hlt_heater picklist + value range + // mlt_sensor picklist + // mlt_heater picklist + value range + // mlt_pump picklist + value range + // hlt_heater_mltfirst 0/1 + // pump_cycle 5..15 + // pump_rest 1..5 + // pump_premash 0/1 + // pump_onmash 0/1 + // pump_mashout 0/1 + // pump_onboil 0/1 + // pump_stop 80..110 + // skip_add 0/1 + // skip_remove 0/1 + // skip_iodine 0/1 + // iodine_time 0..90 + // whirlpool 0/1 + // PID_hlt + // PID_mlt + } + if (debug) fprintf(stdout, "End edit brewsystem %d %s\n", unit->number, unit->uuid); } @@ -113,19 +268,19 @@ for (;;) { if (debug) fprintf(stdout, "setup() option=%d\n", option); - prompt(0); - prompt(102); - prompt(option); + prompt(0, NULL); + prompt(102, NULL); + prompt(option, NULL); if (option == 202) - prompt(402); + prompt(402, NULL); #ifdef USE_SIMULATOR else if (option == 205) #else else if (option == 204) #endif - prompt(404); + prompt(404, NULL); else - prompt(403); + prompt(403, NULL); key = keywait(); @@ -142,6 +297,22 @@ option++; } + if (key == KEY_ENTER) { + switch(option) { + case 202: // recipes + break; + case 203: editUnit(Config.units); /* If more units, via a selector */ + break; + case 204: // devices + break; +#ifdef USE_SIMULATOR + case 205: // simulator + break; +#endif + } + if (my_shutdown) + return; + } } } diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/slcd.c --- a/brewco/slcd.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/slcd.c Wed Dec 02 17:16:41 2015 +0100 @@ -138,9 +138,21 @@ -//void slcdCharDef(int fd, int index, unsigned char data[8]) -//{ -//} +void slcdCharDef(int fd, int index, unsigned char data[8]) +{ + int i; + uint16_t byte; + + if (debug) + fprintf(stdout, "CharDef(%d, %d, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x)\n", fd, index, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); + + byte = SLCD_CGRAM | ((index & 7) << 3); + putLCDsocket(fd, byte); + for (i = 0; i < 8; i++) { + byte = data[i] & 0xff; + putLCDsocket(fd, byte); + } +} diff -r 1193bd7d460f -r 6b80a37fdf8d brewco/slcd.h --- a/brewco/slcd.h Sat Nov 28 21:00:29 2015 +0100 +++ b/brewco/slcd.h Wed Dec 02 17:16:41 2015 +0100 @@ -6,6 +6,7 @@ void slcdLEDs(int fd); void slcdClear(int fd); void slcdPosition(int fd, int x, int y); +void slcdCharDef(int fd, int index, unsigned char data[8]); void slcdPutchar(int fd, unsigned char c); void slcdPuts(int fd, const char *string); void slcdPrintf(int fd, const char *message, ...); diff -r 1193bd7d460f -r 6b80a37fdf8d brewpanel/sdlgui.c --- a/brewpanel/sdlgui.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewpanel/sdlgui.c Wed Dec 02 17:16:41 2015 +0100 @@ -245,6 +245,63 @@ +void SDLGui_CGChar(SGOBJ *dlg, int fd, int x, int y, Uint8 data[8]) +{ + int i, j, x1, x2, y1, y2, dstpitch = 0; + SDL_Rect sr, dr; + Uint32 bg; + Uint8 *dstbits = NULL, mask; + SDL_Surface *CGchar; + SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {53, 59, 61, 0}}; + + CGchar = SDL_CreateRGBSurface(SDL_SWSURFACE, 10, 16, 8, 0, 0, 0, 0); + if (CGchar == NULL) { + fprintf(stderr, "SDLGui_CGChar Can not init font graphics!\n"); + return; + } + dstbits = (Uint8 *)CGchar->pixels; + dstpitch = CGchar->pitch; + mask = 0x10; + i = j = 0; + + /* + * Create a bitmap with the character pixels + */ + for (y1 = 0; y1 < 8; y1++) { + for (y2 = 0; y2 < 2; y2++) { + j = 0; + for (x1 = 0; x1 < 5; x1++) { + for (x2 = 0; x2 < 2; x2++) { + dstbits[j] = (data[i] & mask) ? 1 : 0; + j++; + } + mask >>= 1; + if (! mask) + mask = 0x10; + } + dstbits += dstpitch; + } + i++; + } + + SDL_SetColors(CGchar, blackWhiteColors, 0, 2); + SDL_SetColorKey(CGchar, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0); + bg = LCDbg0; + + sr.x = sr.y = 0; + dr.x = x; + dr.y = y; + sr.w = dr.w = fontwidth; + sr.h = dr.h = fontheight; + + SDL_FillRect(pSdlGuiScrn, &dr, bg); + SDL_BlitSurface(CGchar, &sr, pSdlGuiScrn, &dr); + SDL_UpdateRect(pSdlGuiScrn, x, y, fontwidth, fontheight); + SDL_FreeSurface(CGchar); +} + + + /* * Draw a text character */ diff -r 1193bd7d460f -r 6b80a37fdf8d brewpanel/sdlgui.h --- a/brewpanel/sdlgui.h Sat Nov 28 21:00:29 2015 +0100 +++ b/brewpanel/sdlgui.h Wed Dec 02 17:16:41 2015 +0100 @@ -51,6 +51,7 @@ void SDLGui_LED(SGOBJ *dlg, int fd, int LED, int on); void SDLGui_Cursor(SGOBJ *dlg, int fd, int x, int y, int on, int blink); +void SDLGui_CGChar(SGOBJ *dlg, int fd, int x, int y, Uint8 dataf[8]); void SDLGui_Char(SGOBJ *dlg, int fd, int x, int y, Uint8 c); void SDLGui_DrawLCD(SGOBJ *bdlg, int objnum); int SDLGui_Init(void); diff -r 1193bd7d460f -r 6b80a37fdf8d brewpanel/slcd.c --- a/brewpanel/slcd.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewpanel/slcd.c Wed Dec 02 17:16:41 2015 +0100 @@ -141,8 +141,9 @@ struct slcdDataStruct *lcd = slcds [fd]; int i; - for (i = 0 ; i < 8 ; i++) + for (i = 0 ; i < 8 ; i++) { lcd->cgram[index][i] = data[i]; + } } @@ -152,7 +153,13 @@ { struct slcdDataStruct *lcd = slcds [fd]; - SDLGui_Char(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, data); + if (data < 16) + /* + * Character 0..7 and 8..15 are the same. + */ + SDLGui_CGChar(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->cgram[data & 0x07]); + else + SDLGui_Char(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, data); if (++lcd->cx == lcd->cols) { lcd->cx = 0; diff -r 1193bd7d460f -r 6b80a37fdf8d brewpanel/sockio.c --- a/brewpanel/sockio.c Sat Nov 28 21:00:29 2015 +0100 +++ b/brewpanel/sockio.c Wed Dec 02 17:16:41 2015 +0100 @@ -38,10 +38,11 @@ void socket_recv(SGOBJ *dlg) { uint16_t data; + unsigned char cgdata[8]; struct sockaddr_in clntaddr; socklen_t clntlen = sizeof(clntaddr); ssize_t recv_len; - int fd = 0, my_error; + int i, index, fd = 0, my_error; recv_len = recvfrom(sock, &data, sizeof(uint16_t), MSG_DONTWAIT, (struct sockaddr *)&clntaddr, &clntlen); if (recv_len == sizeof(uint16_t)) { @@ -55,6 +56,22 @@ slcdClear(dlg, fd); } else if ((data & SLCD_MHOME) == SLCD_HOME) { slcdHome(dlg, fd); + } else if ((data & SLCD_MCGRAM) == SLCD_CGRAM) { + index = (data & 0x038) >> 3; + for (i = 0; i < 8; i++) { + /* + * Reply with the current keyboard state. Looks too early but the very last reply + * will be sent at the end of this function and we need to take 8 data words. + */ + if (sendto(sock, &keys, sizeof(uint16_t), MSG_DONTWAIT, (struct sockaddr *) &clntaddr, clntlen) == -1) { + syslog(LOG_NOTICE, "socket_recv() sendto error: %s", strerror(errno)); + } + recv_len = recvfrom(sock, &data, sizeof(uint16_t), 0, (struct sockaddr *)&clntaddr, &clntlen); + cgdata[i] = data & 0x00ff; + } + fprintf(stdout, "Got new CGRAM index=%d, %02x %02x %02x %02x %02x %02x %02x %02x\n", index, + cgdata[0], cgdata[1], cgdata[2], cgdata[3], cgdata[4], cgdata[5], cgdata[6], cgdata[7]); + slcdCharDef(dlg, fd, index, cgdata); } else if ((data & SLCD_MDGRAM) == SLCD_DGRAM) { slcdPosition(dlg, fd, data & 0x001f, (data & 0x0060) >> 5); } else if ((data & 0xfe00) == SLCD_DATA) { diff -r 1193bd7d460f -r 6b80a37fdf8d config.h.in --- a/config.h.in Sat Nov 28 21:00:29 2015 +0100 +++ b/config.h.in Wed Dec 02 17:16:41 2015 +0100 @@ -11,6 +11,8 @@ #define SLCD_MCLEAR 0x1fff #define SLCD_HOME 0x0002 #define SLCD_MHOME 0x1ffe +#define SLCD_CGRAM 0x0040 +#define SLCD_MCGRAM 0x1fc0 #define SLCD_DGRAM 0x0080 #define SLCD_MDGRAM 0x1f80 #define SLCD_DATA 0x0200