/* Copyright 2006 iTuner Corporation */ /* npavel@ituner.com */ #include #include #include #include #include "driver.h" #include "usblcd.h" #include "debug.h" /* private data */ unsigned char keyPressed = 0; /* private functions */ static unsigned int bin2int (char *string) { int len; int i; int n = 0; len = strlen(string); if (len == 0) return n; for (i = 0; i < len; i++) if ((string[i] - '0') > 1 || (string[i] - '0') < 0) return n; else n = n * 2 + ( string[i] - '0'); return n; } static void print_buffer(char *bytes, int len) { int i; if (len > 0) { for (i=0; iline[i] = (char *) malloc (_USBLCD_FONT_MAX_COLS + 1); memset(font->line[i],'0', _USBLCD_FONT_MAX_COLS); } font->id = 0; index++; font++; } while(fgets(line, 255, file)) { if (line[0] == '#') continue; if (strncmp(line, FONT_HEADER, 5) == 0) { found = 1; break; } } if (!found) { fprintf(stderr,"Can't find font file header for file: %s.\n", fontfile); return NULL; } font = chars; while (fgets(line, 255, file)) { if ((line[0] == '#') || (line[0]=='\n') || (line[0]==' ')) continue; font->id = atoi(line); for (i = 0; i< _USBLCD_FONT_MAX_ROWS; i++) { if (!fgets(line, 255, file)) break; snprintf(font->line[i], _USBLCD_FONT_MAX_COLS + 1, "%s",line); } font++; } return chars; } static usblcd_splash_data * get_splash_data(char *splashfile) { FILE *file; usblcd_splash_data *splashes, *splash; char *line; char *tmp; int index = 0; int i; unsigned int found = 0; if ((file = fopen(splashfile, "r")) == NULL) return NULL; line = (char *) malloc (255); if (line == NULL) return NULL; tmp = (char *) malloc (3); if (tmp == NULL) return NULL; splashes = (usblcd_splash_data *) malloc (_USBLCD_MAX_SPLASHES * sizeof(usblcd_splash_data)); if (splashes == NULL) return NULL; splash = splashes; while (index < _USBLCD_MAX_SPLASHES) { for (i = 0; i<_USBLCD_MAX_ROWS + 1; i++) { splash->line[i] = (char *) malloc (_USBLCD_MAX_COLS + 1 + 1); memset(splash->line[i],' ',_USBLCD_MAX_COLS + 1); } splash->min = 0; splash->sec = 0; splash->jump = 0; splash->repeat = 0; splash->leds = 0; splash++; index++; } while(fgets(line, 255, file)) { if (line[0] == '#') continue; if (strncmp(line, SPLASH_HEADER, 5) == 0) { found = 1; break; } } if (!found) { fprintf(stderr,"Can't find splash file header for file: %s.\n", splashfile); return NULL; } splash = splashes; while (fgets(line, 255, file)) { if ((line[0] == '#') || (line[0]=='\n')) continue; /* minutes and seconds */ memcpy(tmp, &line[0], 2); splash->min = atoi(tmp); if (splash->min > 59) splash->min = 59; memcpy(tmp, &line[3], 2); splash->sec = atoi(tmp); if (splash->sec > 59) splash->sec = 59; /* next slot jump and repeat */ fgets(line, 255, file); memcpy(tmp, &line[0], 2); splash->jump = atoi(tmp); if (splash->jump > 10) splash->jump = 10; memcpy(tmp, &line[3], 3); splash->repeat = atoi(tmp); if (splash->repeat > 255) splash->repeat = 255; /* leds state (8 chars) */ fgets(line, 255, file); splash->leds = bin2int(line); /* lcd lines text */ for (i = 0; i < _USBLCD_MAX_ROWS + 1; i++) { fgets(line, 255, file); snprintf(splash->line[i], _USBLCD_MAX_COLS + 1 + 1, "%s", line); } splash++; } free(line); free(tmp); return splashes; } /* public functions */ void _usblcd_match(void) { } void _usblcd_init(usblcd_operations *self) { /* no longer needed */ #ifdef USB_DEV_TEST char const SETUP_PACKET_1[] = { 0x14, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00 }; char const SETUP_PACKET_2[] = { 0x20, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00 }; char read_packet[255]; hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 8; params->timeout = HID_TIMEOUT; params->packet =(char *) SETUP_PACKET_1; self->hid->interrupt_write(self->hid->hid_id, params); params->packet = (char *)SETUP_PACKET_2; self->hid->interrupt_write(self->hid->hid_id, params); #endif self->getversion(self); } void _usblcd_debug(int level) { debug_level = level; } void _usblcd_setled(usblcd_operations *self, unsigned int led, unsigned int status) { hid_params *params; if (led > _USBLCD_MAX_LEDS) led = _USBLCD_MAX_LEDS; if (status > 1 || status < 0) status = 0; /* set led bit to 1 or 0 */ if (status) self->leds |= 1 << led; else self->leds &= ~ (1 << led); params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 2; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c%c", OUT_REPORT_LED_STATE, self->leds); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_backlight(usblcd_operations *self, unsigned int status) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 2; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c%c", OUT_REPORT_LCD_BACKLIGHT, status); MESSAGE("Wrinting %s to lcd device %x", params->packet, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_contrast(usblcd_operations *self, unsigned int level) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 2; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c%c", OUT_REPORT_LCD_CONTRAST, level); MESSAGE("Wrinting %c%c to lcd device %x", OUT_REPORT_LCD_CONTRAST, level, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_set_cursor(usblcd_operations *self, unsigned int status) { if (status) self->state->usblcd_cursor = _USBLCD_CURSOR_ON; else self->state->usblcd_cursor = 0; self->control(self); } void _usblcd_set_cursor_blink(usblcd_operations *self, unsigned int status) { if (status) self->state->usblcd_cursor_blink = _USBLCD_CURSOR_BLINK_ON; else self->state->usblcd_cursor_blink = 0; self->control(self); } void _usblcd_set_switch(usblcd_operations *self, unsigned int status) { if (status) self->state->usblcd_switch = _USBLCD_SWITCH_ON; else self->state->usblcd_switch = 0; self->control(self); } void _usblcd_control(usblcd_operations *self) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 2; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c%c", OUT_REPORT_LCD_CONTROL, self->state->usblcd_switch | self->state->usblcd_cursor | self->state->usblcd_cursor_blink); MESSAGE("Wrinting %s to lcd device %x", params->packet, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_clear(usblcd_operations *self) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 1; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c", OUT_REPORT_LCD_CLEAR); MESSAGE("Wrinting %s to lcd device %x", params->packet, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_setchar(usblcd_operations *self, unsigned int row, unsigned int column, char character) { hid_params *params; // unsigned int len; params =(hid_params *) malloc (sizeof(hid_params)); if (row > _USBLCD_MAX_ROWS) row = _USBLCD_MAX_ROWS; if (column > _USBLCD_MAX_COLS) column = _USBLCD_MAX_COLS; params->endpoint = USB_ENDPOINT_OUT + 1; /* message + 4 control bytes row, column,length, character*/ params->packetlen = 5; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c%c%c%c%c", OUT_REPORT_LCD_TEXT, row, column, 1, character); MESSAGE("Wrinting %s to lcd device %x", params->packet, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_settext(usblcd_operations *self, unsigned int row, unsigned int column, char *text) { hid_params *params; unsigned int len; params =(hid_params *) malloc (sizeof(hid_params)); len = strlen(text); if (len > 20) len = 20; if (row > _USBLCD_MAX_ROWS) row = _USBLCD_MAX_ROWS; if (column > _USBLCD_MAX_COLS) column = _USBLCD_MAX_COLS; params->endpoint = USB_ENDPOINT_OUT + 1; /* 3 control bytes row, column, text length*/ params->packetlen = len + 1 + 3; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c%c%c%c%s", OUT_REPORT_LCD_TEXT, row, column, len, text); MESSAGE("Wrinting %s to lcd device %x", params->packet, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_getversion(usblcd_operations *self) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->packetlen = 1; params->timeout = HID_TIMEOUT; params->packet =(char *) malloc (params->packetlen + 1 ); snprintf (params->packet, params->packetlen + 1 , "%c", HID_REPORT_GET_VERSION); MESSAGE("Wrinting %s to lcd device %x", params->packet, self->hid->hiddev->handle); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_enter_flasher_mode(usblcd_operations *self) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->timeout = HID_TIMEOUT; params->packetlen = 3; params->packet = (char *) malloc ( params->packetlen + 1); snprintf(params->packet, params->packetlen + 1, "%c%c%c", HID_REPORT_EXIT_KEYBOARD, FLASHER_TIMEOUT & 0xFF , (FLASHER_TIMEOUT >> 8) & 0xFF); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_exit_flasher_mode(usblcd_operations *self) { hid_params *params; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->timeout = HID_TIMEOUT; params->packetlen = 3; params->packet = (char *) malloc ( params->packetlen + 1); snprintf(params->packet, params->packetlen + 1, "%c%c%c", HID_REPORT_EXIT_FLASHER, FLASHER_TIMEOUT & 0xFF , (FLASHER_TIMEOUT >> 8) & 0xFF); self->hid->interrupt_write(self->hid->hiddev->handle, params); free(params->packet); free(params); } void _usblcd_setfont(usblcd_operations *self, char *filename) { hid_params *params; usblcd_font_data *buffer, *font; buffer = get_font_data(filename); if (buffer == NULL) return; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->timeout = HID_TIMEOUT; params->packetlen = 10; params->packet = (char *) malloc ( params->packetlen + 1); font = buffer; while (font->id <= _USBLCD_MAX_FONTS && font->id > 0 ) { memset(params->packet,' ', params->packetlen); snprintf(params->packet, params->packetlen + 1, "%c%c%c%c%c%c%c%c%c%c", OUT_REPORT_LCD_FONT, font->id - 1, bin2int(font->line[0]), bin2int(font->line[1]), bin2int(font->line[2]), bin2int(font->line[3]), bin2int(font->line[4]), bin2int(font->line[5]), bin2int(font->line[6]), bin2int(font->line[7])); font++; #ifdef DEBUG print_buffer(params->packet, params->packetlen); #endif self->hid->interrupt_write(self->hid->hiddev->handle, params); } free(params->packet); free(params); free(buffer); } void _usblcd_setfont_memory(usblcd_operations *self, int fontlines[], int nrchars) { hid_params *params; usblcd_font_data *font; int i; params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->timeout = HID_TIMEOUT; params->packetlen = 10; params->packet = (char *) malloc ( params->packetlen + 1); for (i = 0; i < nrchars; i++) { memset(params->packet,' ', params->packetlen); snprintf(params->packet, params->packetlen + 1, "%c%c%c%c%c%c%c%c%c%c", OUT_REPORT_LCD_FONT, i, fontlines[i*8],fontlines[i*8+1], fontlines[i*8+2],fontlines[i*8+3],fontlines[i*8+4],fontlines[i*8+5],fontlines[i*8+6],fontlines[i*8+7]); font++; #ifdef DEBUG print_buffer(params->packet, params->packetlen); #endif self->hid->interrupt_write(self->hid->hiddev->handle, params); } free(params->packet); free(params); } void _usblcd_setsplash(usblcd_operations *self, char *filename) { hid_params *params; usblcd_splash_data *buffer, *splash; char * splashes_text; int i; int index; int offset; int splashes_size; int splash_size; unsigned long ftime = 0; unsigned long faddr = 0; splash_size = (_USBLCD_MAX_COLS + 1 + 1); splashes_size = splash_size * (_USBLCD_MAX_ROWS + 1) * _USBLCD_MAX_SPLASHES + _USBLCD_MAX_SPLASHES * 4; /* 4 control bytes */ buffer = get_splash_data(filename); if (buffer == NULL) return; splashes_text = (char *) malloc (splashes_size); if (splashes_text == NULL) return; memset(splashes_text, 0x00, splashes_size); params =(hid_params *) malloc (sizeof(hid_params)); params->endpoint = USB_ENDPOINT_OUT + 1; params->timeout = HID_TIMEOUT; params->packetlen = _USBLCD_MAX_DATA_LEN; params->packet = (char *) malloc ( params->packetlen + 1); splash = buffer; index = 0; offset = 0; while (index < _USBLCD_MAX_SPLASHES) { if ((splash->min <= -1) || (splash->sec <= -1)) ftime = 0xFFFF; else ftime = splash->min * 60 + splash->sec; for (i = 0; i < _USBLCD_MAX_ROWS + 1; i++) { if (i == 0) { snprintf(splashes_text + offset, 5 + 1, "%c%c%c%c%c", ftime & 0xFF, (ftime >> 8) & 0xFF, splash->jump, splash->repeat, splash->leds); //snprintf(splashes_text + offset, 3 + 1, "%c%c%c", ftime & 0xFF, (ftime >> 8) & 0xFF, splash->leds); offset += 5; //fprintf (stderr, "\nHeader: %02x%02x%02x%02x%02x\n",ftime & 0xFF, (ftime >> 8) & 0xFF, splash->jump, splash->repeat, splash->leds); } memcpy(splashes_text + offset , splash->line[i], splash_size); offset = offset + splash_size; } splash++; index++; } offset = 0; while (offset < splashes_size) { memset(params->packet,' ', params->packetlen); snprintf(params->packet, 4 + 1, "%c%c%c%c", OUT_REPORT_INT_EE_WRITE, (faddr & 0xFF), ((faddr >> 8) & 0xFF), 0x14); if ((offset + _USBLCD_MAX_DATA_LEN - 4) > splashes_size) memcpy(params->packet + 4 , splashes_text + offset, 10); else memcpy(params->packet + 4 , splashes_text + offset, _USBLCD_MAX_DATA_LEN - 4); offset += _USBLCD_MAX_DATA_LEN - 4; faddr += _USBLCD_MAX_DATA_LEN - 4; print_buffer(params->packet, params->packetlen); index++; self->hid->interrupt_write(self->hid->hiddev->handle, params); self->read_events(self); } free(params->packet); free(params); free(buffer); free(splashes_text); } void _usblcd_flash(usblcd_operations *self) { } /* todo: get keystate from circular buffer */ void _usblcd_keystate(usblcd_operations *self) { } /* todo: get irdata from circular buffer */ void _usblcd_irdata(usblcd_operations *self) { } /* todo: get powerstate from circular buffer */ void _usblcd_powerstate(usblcd_operations *self) { } /* for now only reports to stderr */ /* todo: add events to circular buffer */ void _usblcd_read_events(usblcd_operations *self) { int ret = -1; // int const READ_PACKET_LEN = 24; unsigned char read_packet[255]; memset(read_packet,0,255); //hid_set_idle(self->hid->hiddev->handle, 0, 0); memset(read_packet,0,24); ret = usb_interrupt_read(self->hid->hiddev->handle, USB_ENDPOINT_IN + 1, read_packet, _USBLCD_MAX_DATA_LEN, 10); if (ret > 0) { switch (read_packet[0]) { case IN_REPORT_KEY_STATE: { // fprintf(stderr,"\nKEY: x%02x x%02x\n", read_packet[1], read_packet[2]); keyPressed = read_packet[1]; } break; case IN_REPORT_IR_DATA: { // fprintf(stderr,"\nIR: "); // print_buffer(&read_packet[2], read_packet[1]); } break; case RESULT_PARAMETER_MISSING: { } break; case RESULT_DATA_MISSING: { } break; case RESULT_BLOCK_READ_ONLY: { } break; case RESULT_BLOCK_TOO_BIG: { } break; case RESULT_SECTION_OVERFLOW: { } break; case HID_REPORT_GET_VERSION: { } break; case HID_REPORT_ERASE_MEMORY: { } break; case HID_REPORT_READ_MEMORY: { } break; case HID_REPORT_WRITE_MEMORY: { } break; case IN_REPORT_EXT_EE_DATA: { } break; case IN_REPORT_INT_EE_DATA: { #ifdef DEBUG fprintf(stderr,"IN_REPORT_INT_EE_DATA: "); print_buffer(read_packet, _USBLCD_MAX_DATA_LEN); #endif } break; case OUT_REPORT_EXT_EE_READ: { } break; case OUT_REPORT_EXT_EE_WRITE: { } break; case OUT_REPORT_INT_EE_READ: { } break; case OUT_REPORT_INT_EE_WRITE: { } break; case HID_REPORT_EXIT_FLASHER: { } break; case HID_REPORT_EXIT_KEYBOARD: { } break; default: { } } } } void _usblcd_keyevents(usblcd_operations *self, unsigned int *key, unsigned int *status) { _usblcd_read_events(self); *key = keyPressed; status = 0; } void _usblcd_close(usblcd_operations *self) { if (self->hid->hiddev->handle) self->hid->close(self->hid->hiddev->handle); free(self->hid); free(self); } usblcd_operations *new_usblcd_operations(void) { usblcd_operations *this; this = (usblcd_operations *) malloc(sizeof(usblcd_operations)); this->state = (usblcd_state *) malloc(sizeof(usblcd_state)); this->state->usblcd_switch = _USBLCD_SWITCH_ON; this->state->usblcd_cursor = 0; this->state->usblcd_cursor_blink = 0; this->leds = 0; this->match = _usblcd_match; this->init = _usblcd_init; this->debug = _usblcd_debug; this->setled = _usblcd_setled; this->backlight = _usblcd_backlight; this->contrast = _usblcd_contrast; this->set_cursor = _usblcd_set_cursor; this->set_cursor_blink = _usblcd_set_cursor_blink; this->set_switch = _usblcd_set_switch; this->enter_flasher_mode = _usblcd_enter_flasher_mode; this->exit_flasher_mode = _usblcd_exit_flasher_mode; this->control = _usblcd_control; this->clear = _usblcd_clear; this->setchar = _usblcd_setchar; this->settext = _usblcd_settext; this->setfont = _usblcd_setfont; this->setfontmemory = _usblcd_setfont_memory; this->setsplash = _usblcd_setsplash; this->getversion = _usblcd_getversion; this->flash = _usblcd_flash; this->powerstate = _usblcd_powerstate; this->read_events = _usblcd_read_events; this->keystate = _usblcd_keystate; this->keyevents = _usblcd_keyevents; this->irdata = _usblcd_irdata; this->close = _usblcd_close; this->hid = new_hid_operations(); MESSAGE("Device: %x", this->hid->hiddev->handle); return this; }