Here is the same example modified to use direct Libusb commands for handling the display instead of the Windows DLL. This should be quite portable for different environments.
Code:
#include "usb.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define USBD480_VID 0x16C0
#define USBD480_PID 0x08A6
#define USBD480_SET_ADDRESS 0xC0 // set sdram address
#define USBD480_SET_FRAME_START_ADDRESS 0xC4 // set frame start address
static struct usb_device *find_usbd480(void)
{
struct usb_bus *usb_bus;
struct usb_device *dev;
usb_find_busses();
usb_find_devices();
for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next) {
for (dev = usb_bus->devices; dev; dev = dev->next) {
if ((dev->descriptor.idVendor == USBD480_VID) &&
(dev->descriptor.idProduct == USBD480_PID))
return dev;
}
}
return NULL;
}
int main(int argc, char* argv[])
{
struct usb_device *usbdev;
usb_dev_handle *usb_handle = NULL;
int result;
unsigned int addr;
unsigned int writesize;
int width = 480;
int height = 272;
usb_init();
usbdev = find_usbd480();
if(usbdev)
{
usb_handle = usb_open(usbdev);
if(usb_handle==NULL)
printf("error: usb_open\n");
if(usb_set_configuration(usb_handle, 1) < 0)
{
printf("error: setting config 1 failed\n");
printf("%s\n", usb_strerror() );
usb_close(usb_handle);
return 0;
}
if(usb_claim_interface(usb_handle, 0) < 0)
{
printf("error: claiming interface 0 failed\n");
printf("%s\n", usb_strerror() );
usb_close(usb_handle);
return 0;
}
cairo_surface_t * surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
cairo_t * cr = cairo_create (surface);
/* Normalize our context to a (width, height) of (1.0, 1.0) by scaling by our window width and height. */
//cairo_scale (cr, height, height);
//cairo_scale (cr, 1, 1);
/* draw the entire context white. */
cairo_set_source_rgba (cr, 1, 1, 1, 1);
cairo_paint(cr);
/* who doesn't want all those nice line settings :) */
//cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
//cairo_set_line_width(cr, 0.1);
cairo_set_line_width(cr, 1);
cairo_set_source_rgba (cr, 0, 0, 1, 1);
cairo_move_to(cr, 0, 0);
//cairo_line_to(cr, 0.5, 0.5);
cairo_line_to(cr, 100, 100);
cairo_stroke (cr);
static unsigned int count = 0;
static double const trs[8][8] = {
{ 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
{ 1.0, 0.0, 0.15, 0.30, 0.5, 0.65, 0.8, 0.9 },
{ 0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65, 0.8 },
{ 0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5, 0.65},
{ 0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3, 0.5 },
{ 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15, 0.3 },
{ 0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, 0.15 },
{ 0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0, 0.0, }
};
cairo_translate(cr, width / 2, height /2);
int i = 0;
for (i = 0; i < 8; i++)
{
cairo_set_line_width(cr, 3);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
cairo_set_source_rgba(cr, 0, 0, 0, trs[count%8][i]);
cairo_move_to(cr, 0.0, -10.0);
cairo_line_to(cr, 0.0, -40.0);
cairo_rotate(cr, M_PI/4);
cairo_stroke(cr);
}
cairo_set_source_rgba (cr, 0, 0, 0, 1);
cairo_identity_matrix(cr);
cairo_translate(cr, 30, 30);
cairo_move_to(cr, 0.0, 20.0);
cairo_line_to(cr, 0.0, -20.0);
cairo_stroke(cr);
cairo_move_to(cr, 20.0, 0.0);
cairo_line_to(cr, -20.0, 0.0);
cairo_stroke(cr);
cairo_identity_matrix(cr);
cairo_translate(cr, 480-30, 30);
cairo_move_to(cr, 0.0, 20.0);
cairo_line_to(cr, 0.0, -20.0);
cairo_stroke(cr);
cairo_move_to(cr, 20.0, 0.0);
cairo_line_to(cr, -20.0, 0.0);
cairo_stroke(cr);
cairo_identity_matrix(cr);
cairo_translate(cr, 480-30, 272-30);
cairo_move_to(cr, 0.0, 20.0);
cairo_line_to(cr, 0.0, -20.0);
cairo_stroke(cr);
cairo_move_to(cr, 20.0, 0.0);
cairo_line_to(cr, -20.0, 0.0);
cairo_stroke(cr);
cairo_identity_matrix(cr);
cairo_translate(cr, 30, 272-30);
cairo_move_to(cr, 0.0, 20.0);
cairo_line_to(cr, 0.0, -20.0);
cairo_stroke(cr);
cairo_move_to(cr, 20.0, 0.0);
cairo_line_to(cr, -20.0, 0.0);
cairo_stroke(cr);
// some text
cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 0.10);
cairo_show_text (cr, "Hello world!");
// now draw cairo buffer to display
unsigned char* surface_data;
unsigned char rgb565_buf[262144];
unsigned short *outbuf;
int r2,g2,b2;
outbuf = (unsigned short *)&rgb565_buf;
surface_data = cairo_image_surface_get_data (surface);
// conversion from 32 bit RGB to 16 bit RGB565
for(int i=0; i<480*272; i++)
{
b2 = (*surface_data++ & 0xf8) >> 3;
g2 = (*surface_data++ & 0xfc) << 3;
r2 = (*surface_data++ & 0xf8) << 8;
*surface_data++;
*outbuf++ = r2 | g2 | b2;
}
writesize = 262144;
addr = 0;
result = usb_control_msg( usb_handle, 0x40, USBD480_SET_ADDRESS, addr, (addr>>16)&0xffff, NULL, 0, 500);
if(result = usb_bulk_write( usb_handle, 0x02, (char*)rgb565_buf, writesize, 500) != writesize)
printf("bulk_write error %d\n", result);
cairo_destroy (cr);
cairo_surface_destroy (surface);
usb_release_interface(usb_handle, 0);
usb_close(usb_handle);
}
else
{
printf("No USBD480 device found\n");
}
return 0;
}