#include #include #include #include #include #include #define IDBYTE 0x74 // USB interface #define return_message(...) do { fprintf(stderr, __VA_ARGS__); return; } while(0) #define retval_message(retval, ...) do { fprintf(stderr, __VA_ARGS__); return retval; } while(0) #define USB_VENDOR 0x8482 #define USB_DEVICE 0x1003 #define TSTEP 50000 int hw_write_byte(struct ftdi_context *ctx, unsigned char val) { if(ftdi_write_data(ctx, (void *)&val, 1)<1) retval_message(1, "Error: write failed\n"); return 0; } int hw_write_bytes(struct ftdi_context *ctx, unsigned char *val, int n) { if(ftdi_write_data(ctx, (void *)val, n)=0); while(1) { if((res=ftdi_read_data(ctx, val, 1))==1) return 0; if(res<0) retval_message(1, "Error: read failed: %s\n", ctx->error_str); if(timeout>0) usleep(TSTEP); if(tvl) { timeout -= TSTEP; if(timeout<=0) return -1; } } } struct ftdi_context *hw_open_board(char *serial) { struct ftdi_context *ctx = calloc(1, sizeof(struct ftdi_context)); ftdi_init(ctx); if(ftdi_usb_open_desc(ctx, USB_VENDOR, USB_DEVICE, NULL, serial)) retval_message(NULL, "Error: opening device %s failed\n", serial?serial:""); ftdi_usb_purge_buffers(ctx); return ctx; } void hw_close_board(struct ftdi_context *ctx) { ftdi_deinit(ctx); } void write_byte(unsigned char val, unsigned char *buf, int *ptr) { int i; for(i=7; i>=0; i--) { buf[(*ptr)++] = 0x00|(((val>>i)&1)<<1); buf[(*ptr)++] = 0x01|(((val>>i)&1)<<1); } } #define INDEX 0x00 #define DATA 0x02 void write_reg(struct ftdi_context *ctx, unsigned short index, unsigned short data) { unsigned char buf[1024]; int ptr = 0; buf[ptr++] = 0x00; write_byte(IDBYTE|INDEX, buf, &ptr); write_byte(index>>8, buf, &ptr); write_byte(index, buf, &ptr); buf[ptr++] = 0x04; buf[ptr++] = 0x00; write_byte(IDBYTE|DATA, buf, &ptr); write_byte(data>>8, buf, &ptr); write_byte(data, buf, &ptr); buf[ptr++] = 0x04; hw_write_bytes(ctx, buf, ptr); } unsigned short initcode[] = { 0x00, 0x0001, 0xFFFF, 20, 0x08, 0x0303, 0x02, 0x0500, 0x01, 0x010B, 0x0B, 0x4001, 0x30, 0x0000, 0x31, 0x0000, 0x32, 0x0000, 0x33, 0x0401, 0x34, 0x0707, 0x35, 0x0707, 0x36, 0x0707, 0x37, 0x0104, 0x38, 0x0004, 0x39, 0x0004, 0x41, 0x0280, 0x42, 0x8300, 0x43, 0x9F9F, 0x11, 0x0001, 0x12, 0x0008, 0x13, 0x100E, 0x10, 0x0044, 0x12, 0x0018, 0x40, 0x0000, 0x41, 0x0000, 0x42, 0x5F00, 0xFFFF, 40, 0x13, 0x300C, 0xFFFF, 60, 0x10, 0x4340, 0xFFFF, 100, 0x21, 0x0004, 0x44, 0x8304, 0x45, 0x7F00, 0x07, 0x0205, 0xFFFF, 40, 0x07, 0x0227, 0xFFFF, 1, 0x03, 0x1030, 0x0D, 0x3336, 0x07, 0x1237, 0xFFFF, 0xFFFF, }; int main(int argc, char *argv[]) { struct ftdi_context *usb; int i, x, y, r, g, b; float a, c, w; unsigned char buf[4096]; int ptr; usb = hw_open_board(NULL); if(!usb) return 1; ftdi_set_bitmode(usb, 0x07, BITMODE_BITBANG); ftdi_set_baudrate(usb, 230400); for(i=0; ; i+=2) { if(initcode[i] == 0xFFFF) { if(initcode[i+1] == 0xFFFF) break; usleep(initcode[i+1]*1000); } else write_reg(usb, initcode[i], initcode[i+1]); } write_reg(usb, 0x44, 0x7F00); write_reg(usb, 0x45, 0x5F00); write_reg(usb, 0x21, 0x0000); write_reg(usb, 0x23, 0x0000); write_reg(usb, 0x24, 0x0000); ptr = 0; buf[ptr++] = 0x00; write_byte(IDBYTE|INDEX, buf, &ptr); write_byte(0x00, buf, &ptr); write_byte(0x22, buf, &ptr); buf[ptr++] = 0x04; buf[ptr++] = 0x00; write_byte(IDBYTE|DATA, buf, &ptr); hw_write_bytes(usb, buf, ptr); ptr = 0; for(y=0; y<96; y++) for(x=0; x<128; x++) { a = (y/48.0f)*3.14159f; w = x/127.0f; c = (w<0.5f)?w:(1.0f-w); r = (int)(31.0f*w+31.0f*c*cos(a)); g = (int)(63.0f*w+63.0f*c*cos(a+2*3.14159f/3.0f)); b = (int)(31.0f*w+31.0f*c*cos(a+4*3.14159f/3.0f)); write_byte((r<<3)|(g>>3), buf, &ptr); write_byte((g<<5)|b, buf, &ptr); if(ptr>=4080) { hw_write_bytes(usb, buf, ptr); ptr = 0; } } buf[ptr++] = 0x04; hw_write_bytes(usb, buf, ptr); hw_close_board(usb); return 0; }