From: Nils Faerber Date: Sat, 23 Jul 2011 19:32:08 +0000 (+0200) Subject: Implement PBM read file and display X-Git-Url: https://git.kernelconcepts.de/?p=metawatch.git;a=commitdiff_plain;h=a32e1e3a9f9e81bbf05beac619d1feb4941efc46 Implement PBM read file and display --- diff --git a/crc16ccitt.c b/crc16ccitt.c index d468c80..ae0efe3 100644 --- a/crc16ccitt.c +++ b/crc16ccitt.c @@ -1,5 +1,5 @@ /* - * derived from crctester.c + * derived from crctester.c 2011 by Nils Faerber * original header: * ---------------------------------------------------------------------------- * CRC tester v1.3 written on 4th of February 2003 by Sven Reifegerste (zorc/reflex) @@ -100,12 +100,19 @@ static unsigned long crctablefast (unsigned char* p, unsigned long len) unsigned long crc = crcinit_direct; - if (refin) crc = reflect(crc, order); + if (refin) + crc = reflect(crc, order); + + if (!refin) + while (len--) + crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^ *p++]; + else + while (len--) + crc = (crc >> 8) ^ crctab[ (crc & 0xff) ^ *p++]; - if (!refin) while (len--) crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^ *p++]; - else while (len--) crc = (crc >> 8) ^ crctab[ (crc & 0xff) ^ *p++]; + if (refout^refin) + crc = reflect(crc, order); - if (refout^refin) crc = reflect(crc, order); crc^= crcxor; crc&= crcmask; @@ -114,8 +121,8 @@ static unsigned long crctablefast (unsigned char* p, unsigned long len) static unsigned long crctable (unsigned char* p, unsigned long len) { - // normal lookup table algorithm with augmented zero bytes. - // only usable with polynom orders of 8, 16, 24 or 32. + /* normal lookup table algorithm with augmented zero bytes. */ + /* only usable with polynom orders of 8, 16, 24 or 32. */ unsigned long crc = crcinit_nondirect; @@ -138,6 +145,7 @@ static unsigned long crctable (unsigned char* p, unsigned long len) if (refout^refin) crc = reflect(crc, order); + crc^= crcxor; crc&= crcmask; @@ -148,8 +156,8 @@ static unsigned long crctable (unsigned char* p, unsigned long len) unsigned long crcbitbybit(unsigned char* p, unsigned long len) { - // bit by bit algorithm with augmented zero bytes. - // does not use lookup table, suited for polynom orders between 1...32. + /* bit by bit algorithm with augmented zero bytes. */ + /* does not use lookup table, suited for polynom orders between 1...32. */ unsigned long i, j, c, bit; unsigned long crc = crcinit_nondirect; @@ -179,6 +187,7 @@ unsigned long crcbitbybit(unsigned char* p, unsigned long len) { if (refout) crc=reflect(crc, order); + crc ^= crcxor; crc &= crcmask; @@ -365,3 +374,4 @@ int main() { return(0); } #endif + diff --git a/metawatch.c b/metawatch.c index 17cd6ba..3d11045 100644 --- a/metawatch.c +++ b/metawatch.c @@ -1,8 +1,9 @@ /* - * (c) 2011 Siegen, Germany by Nils Faerber + * (c) 2011 Siegen, Germany by Nils Faerber * * license LGPL */ + #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include "metawatch_protocol.h" #include "crc16ccitt.h" @@ -47,7 +49,9 @@ int mw_send_frame(int mw_fd, unsigned char msg_type, unsigned char options, unsi crc = crc16ccitt(frame, len+4); *(unsigned short *)(frame+len+4) = crc; +#ifdef DEBUG dump_frame(frame, tlen); +#endif while (((ret = write(mw_fd, frame, tlen)) >= 0) && (tlen > 0)) tlen -= ret; @@ -107,12 +111,12 @@ void mw_configure_watch_mode(int mw_fd, unsigned char mode, unsigned char save, mdata[0] = timeout; /* seconds */ mdata[1] = invert; /* 0=normal, 1=invert */ - mw_send_frame(mw_fd, MW_CONFIGURE_MODE, (mode & 0x0f) | ((save & 0x01) << 3), mdata, 2); + mw_send_frame(mw_fd, MW_CONFIGURE_MODE, (mode & 0x0f) | ((save & 0x01) << 4), mdata, 2); } void mw_update_display(int mw_fd, unsigned char mode, unsigned char copy) { - mw_send_frame(mw_fd, MW_UPDATE_DISPLAY, (mode & 0x0f) | ((copy & 0x01) << 3), NULL, 0); + mw_send_frame(mw_fd, MW_UPDATE_DISPLAY, (mode & 0x0f) | ((copy & 0x01) << 4), NULL, 0); } void mw_load_template(int mw_fd, unsigned char mode, unsigned char template_select) @@ -125,7 +129,7 @@ void mw_load_template(int mw_fd, unsigned char mode, unsigned char template_sele */ void mw_write_buffer(int mw_fd, unsigned char mode, - unsigned char numlines, /* number of lines, 0 or 1 */ + unsigned char numlines, /* number of lines, 0=two lines or 1=one line */ unsigned char row_offset, /* start at row_offset in display, e.g. lower part in idle @31 */ unsigned char *buffer, int buflen) { @@ -139,11 +143,11 @@ void mw_write_buffer(int mw_fd, memset(mdata, 0, 32); mdata[0] = row_offset; memcpy((mdata+1), buffer, 12); - if (numlines == 1) { - mdata[0] = row_offset+1; - memcpy((mdata+13), (buffer+12), 12); + if (numlines == 0) { + mdata[13] = row_offset+1; + memcpy((mdata+14), (buffer+12), 12); }; - mw_send_frame(mw_fd, MW_WRITE_BUFFER, (mode & 0x0f) | (((numlines & 0x01)<< 3) & 0x10), mdata, numlines ? 13 : 26); + mw_send_frame(mw_fd, MW_WRITE_BUFFER, (mode & 0x0f) | (((numlines & 0x01)<< 4) & 0x10), mdata, numlines ? 13 : 26); } @@ -187,6 +191,11 @@ void mw_get_battery_voltage_response(int mw_fd, unsigned char *batrsp, int len) fprintf(stderr, "battery is at %dV, %s and %s\n", voltage, power_good ? "power is good" : "power fault", bat_charging ? "charging" : "not charging"); } +void mw_status_change_event(int mw_fd, unsigned char option, unsigned char *statrsp, int len) +{ + fprintf(stderr, "Status change event for mode %s: %s\n", mw_screen_mode_names[option&0x0f], mw_status_string[statrsp[0]]); +} + /* ---------------------------------------------------------------------- */ int decode_frame(int mw_fd, unsigned char *buf, int len) @@ -232,6 +241,9 @@ int decode_frame(int mw_fd, unsigned char *buf, int len) case MW_LOW_BATTERY_BT_OFF_MSG: fprintf(stderr, "Watch battery extremely low - radio will turn off\n"); break; + case MW_STATUS_CHANGE_EVENT: + mw_status_change_event(mw_fd, msgopt, msgdata, len-4-2); + break; default: fprintf(stderr, "Unkown msgtype 0x%02x\n", msgtype); break; @@ -241,6 +253,109 @@ int decode_frame(int mw_fd, unsigned char *buf, int len) } +void bitmap_test(int mw_fd) +{ + /* a nice checker-board pattern */ + unsigned char checkbuf[24] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + }; + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 31, checkbuf, 24); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 33, checkbuf, 24); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 35, checkbuf, 24); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 37, checkbuf, 24); + + mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 1); +} + + +void flip_buffer_bytes(unsigned char invert, unsigned char *buf, int len) +{ + int i; + unsigned char tmp; + + while (len--) { + tmp = 0; + for (i=0; i<8; i++) + tmp |= ((*buf & (1<> i) << (7-i); + // fprintf(stderr, "0x%02x -> 0x%02x\n", *buf, tmp); + *buf = invert ? ~tmp : tmp; + buf++; + } +} + +void bitmap_read(int mw_fd) +{ + int ffd, ret; + char rbuf[256]; + unsigned int width, height, i, x, y; + unsigned int rowlength; + unsigned char *bmapbuf; + unsigned char mw_buf[24]; + + ffd = open("test.pbm", O_RDONLY); + if (ffd < 0) { + perror("open"); + return; + }; + ret = read(ffd, rbuf, 3); + if (rbuf[0] != 'P' || rbuf[1] != '4') { + fprintf(stderr, "not a PBM file\n"); + return; + } + memset(rbuf, 0, 256); + i = 0; + do { + ret = read(ffd, (rbuf+i), 1); + } while (!isspace(rbuf[i++])); + width = atoi(rbuf); + + memset(rbuf, 0, 256); + i = 0; + do { + ret = read(ffd, (rbuf+i), 1); + } while (!isspace(rbuf[i++])); + height = atoi(rbuf); + + fprintf(stderr, "bitmap resolution is %d x %d\n", width, height); + + rowlength = ((width / 8) + 1); + fprintf(stderr, "row length = %d bytes\n", rowlength); + + bmapbuf = malloc(rowlength * height); + + ret = read(ffd, bmapbuf, rowlength * height); + close(ffd); + fprintf(stderr, "read %d of %d bytes\n", ret, rowlength * height); + +#if 0 + fprintf(stderr, "\n"); + for (y=0; y 12) ? 12 : rowlength); + memcpy((mw_buf+12), (bmapbuf+((y+1)*rowlength)), (rowlength > 12) ? 12 : rowlength); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 31+y, mw_buf, 24); + } + mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 1); + + free(bmapbuf); +} + + void process_cmd(char *cmdline, int clinep, int mw_fd) { unsigned char mdata[32]; @@ -285,6 +400,12 @@ void process_cmd(char *cmdline, int clinep, int mw_fd) if (strncmp(cmdline, "svib", 4) == 0) { mw_set_vibrate_mode(mw_fd, 1, 300, 300, 5); } + if (strncmp(cmdline, "tbmp", 4) == 0) { + bitmap_test(mw_fd); + } + if (strncmp(cmdline, "rbmp", 4) == 0) { + bitmap_read(mw_fd); + } } diff --git a/metawatch_protocol.h b/metawatch_protocol.h index f0ad616..8a12075 100644 --- a/metawatch_protocol.h +++ b/metawatch_protocol.h @@ -1,3 +1,9 @@ +/* + * (c) 2011 Siegen, Germany by Nils Faerber + * + * license LGPL + */ + #ifndef _MW_PROT_H #define _MW_PROT_H @@ -50,5 +56,19 @@ #define MW_SCREEN_MODE_NOTIFICATION 0x02 #define MW_SCREEN_MODE_SCROLL 0x03 +const char *mw_screen_mode_names[] = { + "idle screen", + "application screen", + "notification screen", + "scroll" +}; + +const char *mw_status_string[] = { + "Reserved", + "Mode Change", + "Display Timeout" +}; + + #endif