[Libphidget-devel] LCD Screen & SingleServo support for libphidgets
Status: Alpha
Brought to you by:
jstrohm
|
From: Loic D. <lo...@gn...> - 2003-10-16 18:29:12
|
Hi, Here is a patch against the current libphidgets CVS tree to add support for the following devices: idVendor 0x06c2 idProduct 0x0052 bcdDevice 1.00 iManufacturer 1 Phidgets Inc. iProduct 2 PhidgetTextLCD iSerial 3 01559 idVendor 0x0925 idProduct 0x8101 bcdDevice 0.02 iManufacturer 1 GLAB Chester iProduct 2 PhidgetServo iSerial 3 00389 It now works fine (says ./phidgets_c TEXTLCD & ./servo_example ;-) under GNU/Linux, provided you de-activate the hid module. There may be a way to use libusb while the hid module is in place. Cheers, Index: ChangeLog =================================================================== RCS file: /cvsroot/libphidget/libphidget/ChangeLog,v retrieving revision 1.2 diff -u -r1.2 ChangeLog --- ChangeLog 7 Sep 2002 20:12:29 -0000 1.2 +++ ChangeLog 16 Oct 2003 18:01:58 -0000 @@ -0,0 +1,8 @@ +Thu Oct 16 19:49:27 2003 Loic Dachary <lo...@gn...> + + * src/libphidget/phidget.c (phidgetTextLCD*): Add support for 0x06C2 / 0x0052 + +Thu Oct 16 14:01:50 2003 Loic Dachary <lo...@gn...> + + * src/libphidget/phidget.c (phidgetSingleServo): Add support for 0x0925 / 0x8101 + Index: src/libphidget/phidget.c =================================================================== RCS file: /cvsroot/libphidget/libphidget/src/libphidget/phidget.c,v retrieving revision 1.36 diff -u -r1.36 phidget.c --- src/libphidget/phidget.c 15 Aug 2003 02:43:29 -0000 1.36 +++ src/libphidget/phidget.c 16 Oct 2003 18:01:58 -0000 @@ -33,6 +33,100 @@ enum ELPError _libPhidgetError = LPE_NONE; /**< Last lib phidget error */ +/* + * Phidgets Protocol specific values for LCD screens + */ +#define PHIDGET_LCD_PROTOCOL_ESCAPE 0x00 /* If next value in buffer is 0x01 or 0x02, + it will not be interpreted as a + CONTROL_MODE or DATA_MODE switch. */ +#define PHIDGET_LCD_PROTOCOL_CONTROL_MODE 0x01 /* The next values in the buffer are + interpreted according to the + instruction set of the LCD screen + (HD44780 for instance). */ +#define PHIDGET_LCD_PROTOCOL_DATA_MODE 0x02 /* The next values in the buffer are + interpreted as characters to be + written on the screen. */ +#define PHIDGET_LCD_PROTOCOL_BUFFER_SIZE 8 /* Each USB packet must contain exactly + 8 bytes. */ +#define PHIDGET_LCD_PROTOCOL_LENGTH_INDEX 7 /* The number of valid bytes in the packet + must be located in the 7th byte of the + packet. */ +/* + * phidgetDevice->type->vendorID == 0x06C2 && phidgetDevice->type->productID == 0x0052 + * http://www.eio.com/hd44780.pdf page 191 + * http://www.doc.ic.ac.uk/~ih/doc/lcd/pc_example/ + * + * Constants for register values. + */ + +/* + * Turning the backlight of the HD44780 screen is done in a way that + * does not match the LCD_PROTOCOL above. Light is controled by + * black magic ;-) + */ +#define PHIDGET_HD44780_BYTE_0_BACKLIGHT_TURN_ON 0x01 +#define PHIDGET_HD44780_BYTE_7_BACKLIGHT_TURN_ON 0x11 +#define PHIDGET_HD44780_BYTE_0_BACKLIGHT_TURN_OFF 0x00 +#define PHIDGET_HD44780_BYTE_7_BACKLIGHT_TURN_OFF 0x11 + +#define HD44780_CHARACTERS_PER_LINE 20 /* One or two 20 characters lines. */ + +// HD44780 Instruction Set DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 +// ======================= === === === === === === === === +#define HD44780_CLEAR_DISPLAY 0x01 // 0 0 0 0 0 0 0 1 +#define HD44780_RETURN_HOME 0x02 // 0 0 0 0 0 0 1 * +#define HD44780_SET_ENTRY_MODE 0x04 // 0 0 0 0 0 1 I/D S +#define HD44780_SET_DISPLAY 0x08 // 0 0 0 0 1 D C B +#define HD44780_SET_CURSOR_AND_DISPLAY_SHIFT 0x10 // 0 0 0 1 S/C R/L * * +#define HD44780_SET_FUNCTION 0x20 // 0 0 1 DL N F * * +#define HD44780_SET_CGRAM_ADDRESS 0x40 // 0 1 A A A A A A +#define HD44780_SET_DDRAM_ADDRESS 0x80 // 1 A A A A A A A + +// HD44780 Parameters +// ================== +// N.B. explicit values for EVERY corresponding parameter +// ==== MUST be passed each time any instruction is used + +// Set_Entry_Mode +// ============== +#define HD44780_DECREMENT_ADDRESS 0x00 // . . . . . . 0 . +#define HD44780_INCREMENT_ADDRESS 0x02 // . . . . . . 1 . + +#define HD44780_SHIFT_DISPLAY_OFF 0x00 // . . . . . . . 0 +#define HD44780_SHIFT_DISPLAY_ON 0x01 // . . . . . . . 1 + +// Set_Display +// =========== +#define HD44780_DISPLAY_OFF 0x00 // . . . . . 0 . . +#define HD44780_DISPLAY_ON 0x04 // . . . . . 1 . . + +#define HD44780_CURSOR_OFF 0x00 // . . . . . . 0 . +#define HD44780_CURSOR_ON 0x02 // . . . . . . 1 . + +#define HD44780_BLINK_OFF 0x00 // . . . . . . . 0 +#define HD44780_BLINK_ON 0x01 // . . . . . . . 1 + +// Set_Cursor_and_Display_Shift +// ============================ +#define HD44780_CURSOR 0x00 // . . . . 0 . . . +#define HD44780_DISPLAY_AND_CURSOR 0x08 // . . . . 1 . . . + +#define HD44780_LEFT 0x00 // . . . . . 0 . . +#define HD44780_RIGHT 0x04 // . . . . . 1 . . + +// Set_Function +// ============ +#define HD44780_DATA_LENGTH_4 0x00 // . . . 0 . . . . +#define HD44780_DATA_LENGTH_8 0x10 // . . . 1 . . . . + +#define HD44780_ONE_DISPLAY_LINE 0x00 // . . . . 0 . . . +#define HD44780_TWO_DISPLAY_LINES 0x08 // . . . . 1 . . . + +#define HD44780_FONT_5X7 0x00 // . . . . . 0 . . +#define HD44780_FONT_5X10 0x04 // . . . . . 1 . . + +#define HD44780_LINE2_OFFSET 0x40 + /** * Phidget description informatioin. \a deviceClass is specially useful in determining what type of phidget this is. * <b>You should never access any of ht edata members directly.</b> @@ -938,12 +1032,17 @@ _registerDeviceType("QuadServo .1 Degree", 0x06C2, 0x0038, LP_QUAD_SERVO); _registerDeviceType("UniServo .1 Degree", 0x06C2, 0x0039, LP_UNI_SERVO); + _registerDeviceType("UniServo .1 Degree", 0x0925, 0x8101, LP_UNI_SERVO); _registerDeviceType("Interface Kit 4/8/8", 0x0925, 0x8201, LP_INTERFACE_KIT_488); _registerDeviceType("Interface Kit 4/8/8", 0x06C2, 0x0040, LP_INTERFACE_KIT_488); _registerDeviceType("Interface Kit 4/8/8", 0x06C2, 0x0045, LP_INTERFACE_KIT_888); _registerDeviceType("Interface Kit 8/8/0", 0x06C2, 0x0041, LP_INTERFACE_KIT_880); _registerDeviceType("Phidget LCD", 0x06C2, 0x0041, LP_INTERFACE_KIT_880); _registerDeviceType("PhidgetTextLCD ECMA1010 Ver 1.0", 0x06C2, 0x0050,LP_TEXT_LCD); + /* Specifications for the line below at + http://www.eio.com/hd44780.pdf + http://home.iae.nl/users/pouweha/lcd/lcd.shtml */ + _registerDeviceType("PhidgetTextLCD", 0x06C2, 0x0052,LP_TEXT_LCD); _registerDeviceType("RFID VID/PID", 0x06C2, 0x0030, LP_RFID); _registerDeviceType("8-AdvancedServo", 0x06C2, 0x003B, LP_8WAY_SERVO); //_registerDeviceType("Interface Kit 32-32-0", 0x06C2, 0x0042, LP_INTERFACE_KIT); @@ -1282,9 +1381,8 @@ */ enum ELPError phidgetSingleServo(struct phidget *phidgetDevice, float percent) { - int _min=230,_max=(int) (180 * 10.6f + 230)+_min; - int pulse; char buffer[6] = { 0 }; + int buffer_size; DBG("phidgetSingleServo"); @@ -1297,21 +1395,41 @@ if (phidgetDevice->type->deviceClass != LP_UNI_SERVO) return (_error(LPE_WRONG_PHIDGET_CLASS_TYPE)); - //pulse = (int) (((percent) * 180) * 10.6f + 230); + if(phidgetDevice->type->vendorID == 0x0925 && phidgetDevice->type->productID == 0x8101) { + /* + * idVendor 0x0925 + * idProduct 0x8101 + * bcdDevice 0.02 + * iManufacturer 1 GLAB Chester + * iProduct 2 PhidgetServo + * http://sourceforge.net/docman/display_doc.php?docid=12651&group_id=60607 + */ + buffer[0] = 0; /* Index of servo : always 0 on single servo */ + buffer[1] = (int)(percent * 255); /* Semantic is unclear. */ + + buffer_size = 2; + } else { + int _min=230,_max=(int) (180 * 10.6f + 230)+_min; + int pulse; + + //pulse = (int) (((percent) * 180) * 10.6f + 230); + + if (phidgetDevice->extraData!=NULL) + { + int *temp=(int *)phidgetDevice->extraData; + _min=temp[0]; + _max=temp[1]; + } + //pulse = (int) (((percent) * 180) * 10.6f + 230); + pulse=(percent*(_max-_min))+_min; - if (phidgetDevice->extraData!=NULL) - { - int *temp=(int *)phidgetDevice->extraData; - _min=temp[0]; - _max=temp[1]; - } - //pulse = (int) (((percent) * 180) * 10.6f + 230); - pulse=(percent*(_max-_min))+_min; + buffer[0] = pulse % 256; + buffer[1] = (pulse / 256); - buffer[0] = pulse % 256; - buffer[1] = (pulse / 256); + buffer_size = 6; + } - return (phidgetWrite(phidgetDevice, buffer, sizeof(buffer))); + return (phidgetWrite(phidgetDevice, buffer, buffer_size)); } /** @@ -1834,10 +1952,13 @@ */ enum ELPError phidgetTextLCDClear(struct phidget *phidgetDevice) { - phidgetTextLCDWrite(phidgetDevice,0,0," "); - phidgetTextLCDWrite(phidgetDevice,1,0," "); - phidgetTextLCDWrite(phidgetDevice,2,0," "); - phidgetTextLCDWrite(phidgetDevice,3,0," "); + phidgetTextLCDWrite(phidgetDevice,0,0," "); + phidgetTextLCDWrite(phidgetDevice,1,0," "); + if(!(phidgetDevice->type->vendorID == 0x06C2 && phidgetDevice->type->productID == 0x0052)) { + + phidgetTextLCDWrite(phidgetDevice,2,0," "); + phidgetTextLCDWrite(phidgetDevice,3,0," "); + } } /** @@ -1845,13 +1966,29 @@ */ enum ELPError phidgetTextLCDOn(struct phidget *phidgetDevice) { - char buffer[8]; + char buffer[PHIDGET_LCD_PROTOCOL_BUFFER_SIZE] = { 0 }; + int i = 0; + + if(phidgetDevice->type->vendorID == 0x06C2 && phidgetDevice->type->productID == 0x0052) { + buffer[i++] = HD44780_SET_FUNCTION | HD44780_DATA_LENGTH_8 | HD44780_TWO_DISPLAY_LINES | HD44780_FONT_5X7; + buffer[i++] = PHIDGET_LCD_PROTOCOL_ESCAPE; + buffer[i++] = HD44780_CLEAR_DISPLAY; + buffer[i++] = HD44780_SET_DISPLAY | HD44780_DISPLAY_ON | HD44780_CURSOR_ON | HD44780_BLINK_ON; + buffer[PHIDGET_LCD_PROTOCOL_LENGTH_INDEX] = i; + + phidgetWrite(phidgetDevice,buffer,PHIDGET_LCD_PROTOCOL_BUFFER_SIZE); + + memset(buffer, '\0', PHIDGET_LCD_PROTOCOL_BUFFER_SIZE); + buffer[0] = PHIDGET_HD44780_BYTE_0_BACKLIGHT_TURN_ON; + buffer[7] = PHIDGET_HD44780_BYTE_7_BACKLIGHT_TURN_ON; + } else { + buffer[i++] = 0x69; // 0: 0 1 1 0 1 0 0 1 <- System Set, 4 lines, Use CGRAM + buffer[i++] = 0x31; // 0: 0 0 1 1 0 0 0 1 <- Display ON/OFF, Display ON + buffer[i++] = 0x42; // 0: 0 1 0 0 0 0 1 0 <- Power Save, Oscillator Circuit ON + buffer[7] = 3; + } - buffer[0] = 0x69; // 0: 0 1 1 0 1 0 0 1 <- System Set, 4 lines, Use CGRAM - buffer[1] = 0x31; // 0: 0 0 1 1 0 0 0 1 <- Display ON/OFF, Display ON - buffer[2] = 0x42; // 0: 0 1 0 0 0 0 1 0 <- Power Save, Oscillator Circuit ON - buffer[7] = 3; - return(phidgetWrite(phidgetDevice,buffer,8)); + return(phidgetWrite(phidgetDevice,buffer,PHIDGET_LCD_PROTOCOL_BUFFER_SIZE)); } /** @@ -1859,12 +1996,23 @@ */ enum ELPError phidgetTextLCDOff(struct phidget *phidgetDevice) { - char buffer[8]; + char buffer[PHIDGET_LCD_PROTOCOL_BUFFER_SIZE] = { 0 }; + int i = 0; - buffer[0] = 0x30; // 0: 0 0 1 1 0 0 0 0 <- Display ON/OFF, Display ON - buffer[1] = 0x40; // 0: 0 1 0 0 0 0 0 0 <- Power Save, Oscillator Circuit ON - buffer[7] = 2; - return(phidgetWrite(phidgetDevice,buffer,8)); + if(phidgetDevice->type->vendorID == 0x06C2 && phidgetDevice->type->productID == 0x0052) { + buffer[0] = PHIDGET_HD44780_BYTE_0_BACKLIGHT_TURN_OFF; + buffer[7] = PHIDGET_HD44780_BYTE_7_BACKLIGHT_TURN_OFF; + phidgetWrite(phidgetDevice,buffer,PHIDGET_LCD_PROTOCOL_BUFFER_SIZE); + memset(buffer, '\0', PHIDGET_LCD_PROTOCOL_BUFFER_SIZE); + + buffer[i++] = HD44780_SET_DISPLAY | HD44780_DISPLAY_OFF; + } else { + buffer[i++] = 0x30; // 0: 0 0 1 1 0 0 0 0 <- Display ON/OFF, Display ON + buffer[i++] = 0x40; // 0: 0 1 0 0 0 0 0 0 <- Power Save, Oscillator Circuit ON + } + buffer[PHIDGET_LCD_PROTOCOL_LENGTH_INDEX] = i; + + return(phidgetWrite(phidgetDevice,buffer,PHIDGET_LCD_PROTOCOL_BUFFER_SIZE)); } /** @@ -1878,38 +2026,46 @@ { int pos=0,t,len,tc; unsigned char temp[256],buffer[10]; + int max_len = 0; - //temp[pos++] = 0x69; // 0: 0 1 1 0 1 0 0 1 <- System Set, 4 lines, Use CGRAM - //temp[pos++] = 0x31; // 0: 0 0 1 1 0 0 0 1 <- Display ON/OFF, Display ON - //temp[pos++] = 0x42; // 0: 0 1 0 0 0 0 1 0 <- Power Save, Oscillator Circuit ON - temp[pos++] = 0x57; // 0: 0 1 0 1 0 1 1 1 <- RAM Address set to 010111 (23) - temp[pos++] = 0xB0; // Set the address pointer - temp[pos++] = 0x30 + row * 0x10 + 0x80+col; // set position we write to - temp[pos++] = 0x02; // Data mode + if(phidgetDevice->type->vendorID == 0x06C2 && phidgetDevice->type->productID == 0x0052) { + temp[pos++] = HD44780_SET_DDRAM_ADDRESS | (((row % 2) - 1) * HD44780_LINE2_OFFSET); + temp[pos++] = PHIDGET_LCD_PROTOCOL_DATA_MODE; + max_len = HD44780_CHARACTERS_PER_LINE; + } else { + //temp[pos++] = 0x69; // 0: 0 1 1 0 1 0 0 1 <- System Set, 4 lines, Use CGRAM + //temp[pos++] = 0x31; // 0: 0 0 1 1 0 0 0 1 <- Display ON/OFF, Display ON + //temp[pos++] = 0x42; // 0: 0 1 0 0 0 0 1 0 <- Power Save, Oscillator Circuit ON + temp[pos++] = 0x57; // 0: 0 1 0 1 0 1 1 1 <- RAM Address set to 010111 (23) + temp[pos++] = 0xB0; // Set the address pointer + temp[pos++] = 0x30 + row * 0x10 + 0x80+col; // set position we write to + temp[pos++] = 0x02; // Data mode + max_len = 12; + } // Write the string len=strlen(str); - if (len>12) len=12; + if (len>max_len) len=max_len; for (t=0;t<len;t++) temp[pos++]=str[t]; - temp[pos++] = 0x01; // back to command mode + temp[pos++] = PHIDGET_LCD_PROTOCOL_CONTROL_MODE; tc=0; for (t=0;t<pos;t++) { buffer[tc++]=temp[t]; - if (tc==7) + if (tc==PHIDGET_LCD_PROTOCOL_LENGTH_INDEX) { - buffer[7]=7; - phidgetWrite(phidgetDevice,buffer,8); + buffer[PHIDGET_LCD_PROTOCOL_LENGTH_INDEX]=tc; + phidgetWrite(phidgetDevice,buffer,PHIDGET_LCD_PROTOCOL_BUFFER_SIZE); tc=0; } } if (tc!=0) { - buffer[7]=tc; - phidgetWrite(phidgetDevice,buffer,8); + buffer[PHIDGET_LCD_PROTOCOL_LENGTH_INDEX]=tc; + phidgetWrite(phidgetDevice,buffer,PHIDGET_LCD_PROTOCOL_BUFFER_SIZE); } return (_error(LPE_NONE)); |