/* a clock for Dream Cheeky's USB LED panel (21x7 LED module) code by SASANO Takayoshi --- CC-BY-SA */ #include #include #include #include #include #include // libusb /* font data */ static unsigned char digit4x8[][8] = { { 0xe, // ooo- 0xa, // o-o- 0xa, // o-o- 0xa, // o-o- 0xa, // o-o- 0xa, // o-o- 0xe, // ooo- 0x0, }, { 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x0, }, { 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0xe, // ooo- 0x8, // o--- 0x8, // o--- 0xe, // ooo- 0x0, }, { 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0xe, // ooo- 0x0, }, { 0xa, // o-o- 0xa, // o-o- 0xa, // o-o- 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x0, }, { 0xe, // ooo- 0x8, // o--- 0x8, // o--- 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0xe, // ooo- 0x0, }, { 0xe, // ooo- 0x8, // o--- 0x8, // o--- 0xe, // ooo- 0xa, // o-o- 0xa, // o-o- 0xe, // ooo- 0x0, }, { 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x2, // --o- 0x0, }, { 0xe, // ooo- 0xa, // o-o- 0xa, // o-o- 0xe, // ooo- 0xa, // o-o- 0xa, // o-o- 0xe, // ooo- 0x0, }, { 0xe, // ooo- 0xa, // o-o- 0xa, // o-o- 0xe, // ooo- 0x2, // --o- 0x2, // --o- 0xe, // ooo- 0x0, }, { 0x0, // ---- 0x0, // ---- 0x2, // --o- 0x0, // ---- 0x2, // --o- 0x0, // ---- 0x0, // ---- 0x0, }, { 0x0, // ---- 0x0, // ---- 0x0, // ---- 0x0, // ---- 0x0, // ---- 0x0, // ---- 0x0, // ---- 0x0, }, }; /* display one character */ static void display_character(struct usb_dev_handle *dev, unsigned char *data) { int i; /* send data */ for (i = 0; i < 4; i++) { if (usb_control_msg(dev, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0x09, // Set_Report 0x0200, // (Output), no report ID 0x0000, // bInterfaceNumber data + i * 8, 8, 1000) < 0) { printf("usb_control_msg %s\n", usb_strerror()); } } return; } /* reverse bit order (32bit) */ static uint32_t bitrev32(uint32_t val) { val = ((val & 0x0000ffff) << 16) | ((val & 0xffff0000) >> 16); val = ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8); val = ((val & 0x0f0f0f0f) << 4) | ((val & 0xf0f0f0f0) >> 4); val = ((val & 0x33333333) << 2) | ((val & 0xcccccccc) >> 2); val = ((val & 0x55555555) << 1) | ((val & 0xaaaaaaaa) >> 1); return val; } /* clock main */ static void do_clock(struct usb_dev_handle *dev) { int i, h, n; time_t t; struct tm *tm; unsigned char *hr10, *hr1, *colon, *min10, *min1; unsigned char buf[32]; uint32_t row; for (i = 0; i < 4; i++) { buf[i * 8 + 0] = 0; // brightness buf[i * 8 + 1] = i * 2; // row number } n = 0; while (1) { time(&t); tm = localtime(&t); // printf("%d:%d\n", tm->tm_hour, tm->tm_min); h = tm->tm_hour % 12; if (h == 0) h = 12; hr10 = digit4x8[(h >= 10) ? 1 : 11]; hr1 = digit4x8[h % 10]; colon = digit4x8[(n++ & 2) ? 10 : 11]; min10 = digit4x8[tm->tm_min / 10]; min1 = digit4x8[tm->tm_min % 10]; for (i = 0; i < 8; i++) { /* image area: bit[23:3] */ row = (*hr10++ << 20) | (*hr1++ << 16) | (*colon++ << 14) | (*min10++ << 10) | (*min1++ << 6); row = ~bitrev32(row); buf[(i / 2) * 8 + (i & 1) * 3 + 2] = row >> 24; buf[(i / 2) * 8 + (i & 1) * 3 + 3] = row >> 16; buf[(i / 2) * 8 + (i & 1) * 3 + 4] = row >> 8; } display_character(dev, buf); usleep(250000); } return; } /* action */ static void do_action(struct usb_device *dev) { usb_dev_handle *dh; /* open device */ dh = usb_open(dev); if (dh == NULL) { printf("usb_open NULL\n"); goto fin0; } /* set configuration */ if (usb_set_configuration(dh, dev->config->bConfigurationValue) < 0) { printf("usb_set_configuration %s\n", usb_strerror()); goto fin1; } /* claim interface */ if (usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber) < 0) { printf("usb_claim_interface %s\n", usb_strerror()); goto fin1; } /* clock */ do_clock(dh); //fin2: usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber); fin1: usb_close(dh); fin0: return; } /* test main */ static void usb_test(void) { #define VENDOR_ID 0x1d34 #define PRODUCT_ID 0x0013 struct usb_bus *bus; struct usb_device *dev; int found, bnum, dnum; /* initialize libusb */ usb_init(); usb_find_busses(); usb_find_devices(); /* no device as default */ found = 0; /* find device */ for (bus = usb_get_busses(), bnum = 0; bus != NULL; bus = bus->next, bnum++) { for (dev = bus->devices, dnum = 0; dev != NULL; dev = dev->next, dnum++) { if (dev->descriptor.idVendor == VENDOR_ID && dev->descriptor.idProduct == PRODUCT_ID) { found = 1; goto found; } } } found: /* do action when device is found */ if (found) { printf("device at %03d:%03d\n", bnum, dnum); do_action(dev); } else { printf("device not found\n"); } return; } int main(int argc, char *argv[]) { usb_test(); return 0; }