(mostly @mikroe team):
Testing the USB_Host library with HID mouse, I've found some problems. Tests are done on two different hardware platforms, a custom PIC32MX250F128D board and a PIC32MX795F512L Digilent Cerebot board. Both boards are working properly. Project settings are ok, since I use these boards for different other tests.
Tests with two different mice (both working ok on a PC):
1. LG XM-400
2. Omega om06v
Tests 1 and 2 are made with LG XM-400 mouse. The Omega om06v mouse does not work on PIC32MX250F128D.
1. On PIC32MX250F128D, the interrupt routine should contain USBIF_bit := 0;
Code: Select all
procedure USB1Interrupt; iv IVT_USB_1; ilevel 7; ics ICS_SOFT;
begin
USBHost_IntHandler;
USBIF_bit := 0;
end;
In this case, the mouse orange light blinks shortly (once) after being powered and shuts down (no orange light). The interrupt keeps being triggered.
If starting the PIC without a mouse attached, USBHost_Main may get called (see test code below). Attaching the mouse before starting the PIC, USBHost_Main never gets called in main loop (program freezes before calling USBHost_Main).
Adding USBIF_bit := 0 in the interrupt handler, makes the mouse work. (interrupt called at about 1.1KHz)
2. Starting the USB module in host mode (USBHost_Init), with mouse physically attached, sometimes the PIC freezes, even explicitly clearing USBIF_bit.
Connecting the Omega om06v mouse on PIC32MX250F128D triggers the "connected" and "enumerated" events but works no further and the mouse shuts down.
3. On PIC32MX795F512L both mice work, but after more mouse events (move x-y, clicks or scrolls) the mice shut down like described above. On PIC32MX250F128D, the LG XM-400 does not shut down.
This is the test code:
Code: Select all
program TestHIDMouse250F;
var
USBHost_HIDHandler : TUSBHostHIDHandler;
USBHost_HIDHandlerPtr : ^TUSBHostHIDHandler;
PIC_LED1: sbit at LATB.4;
PIC_LED2: sbit at LATC.5;
PIC_LED1_Dir: sbit at TRISB.4;
PIC_LED2_Dir: sbit at TRISC.5;
EnumeratedOK: bit; //for debug
type
TUSBHostHIDMouseReport = record
button: Integer;
x: Integer;
y: Integer;
end;
var
mouseData: TUSBHostHIDMouseReport;
XMouse, YMouse: Integer;
procedure USB1Interrupt; iv IVT_USB_1; ilevel 7; ics ICS_SOFT; //no ICS_SRS on PIC32MX250F128D, so use soft
begin
USBHost_IntHandler;
USBIF_bit := 0; /////////// necessary on PIC32MX250F128D
//PIC_LED2 := not PIC_LED2;
end;
procedure MouseInit();
begin
//PIC_LED2 := 1;
if (USBHost_HIDGetDeviceType() = _USB_HOST_HID_DEVICE_MOUSE) then
begin
// HID Mouse
//PIC_LED2 := 1; //detects mouse OK !
end
else if (USBHost_HIDGetDeviceType() = _USB_HOST_HID_DEVICE_KEYB) then
begin
//HID Keyboard
//PIC_LED2 := 1;
end;
end;
procedure MouseReportReceived(reportData : ^byte);
var
arrCh: array[6] of Short;
i: Byte;
begin
for i := 0 to 5 do
begin
arrCh[i] := reportData^;
reportData := reportData + 1
end;
{ original mikroe's code (for other type of mouse, with higher increment resolution)
mouseData.button := arrCh[0] + (word(arrCh[1]) shl 8);
mouseData.x := arrCh[2] + (word(arrCh[3]) shl 8);
mouseData.y := arrCh[4] + (word(arrCh[5]) shl 8); }
//HID_MOUSE_UpdatePosition(mouseData.x, mouseData.y);
//mouse with 8-bit increment:
mouseData.x := arrCh[1];
mouseData.y := arrCh[2];
mouseData.button := arrCh[0];
{
if mouseData.x < 0 then
begin
XMouse := mouseData.x;
PIC_LED1 := 1;
Delay_ms(1);
PIC_LED1 := 0;
end;
if mouseData.x > 0 then
begin
XMouse := mouseData.x;
PIC_LED2 := 1;
Delay_ms(1);
PIC_LED2 := 0;
end; }
if mouseData.y < 0 then
begin
YMouse := mouseData.y;
PIC_LED1 := 1;
Delay_ms(1);
PIC_LED1 := 0;
end;
if mouseData.y > 0 then
begin
YMouse := mouseData.y;
PIC_LED2 := 1;
Delay_ms(1);
PIC_LED2 := 0;
end;
{ }
{
PIC_LED1 := 0;
PIC_LED2 := 0;
if mouseData.button and 1 = 1 then //left click
PIC_LED1 := 1;
if mouseData.button and 2 = 2 then //right click
PIC_LED2 := 1;
{if mouseData.button and 4 = 4 then //scroll click
LED2 := 1;}
{
if arrCh[3] < 0 then //scroll
begin
XMouse := mouseData.x;
PIC_LED2 := 1;
Delay_ms(1);
PIC_LED2 := 0;
end;
if arrCh[3] > 0 then
begin
XMouse := mouseData.x;
PIC_LED1 := 1;
Delay_ms(1);
PIC_LED1 := 0;
end; {}
end;
procedure HIDEventHandler(event : byte);
begin
if event = _USB_HOST_EVENT_DEVICE_DISCONNECTED then
begin
//PIC_LED2 := not PIC_LED2;
//PIC_LED2 := 1;
end
else
if event = _USB_HOST_EVENT_DEVICE_CONNECTED then
begin
//PIC_LED2 := 1;
//PIC_LED1 := not PIC_LED1;
end
else
if(event = _USB_HOST_EVENT_DEVICE_ENUMERATED) then
begin
//PIC_LED2 := not PIC_LED2;
//PIC_LED2 := 1;
EnumeratedOK := 1; //is enumerated
end
else
if(event = _USB_HOST_EVENT_HOST_ERROR) then
begin
//PIC_LED2 := not PIC_LED2;
end;
end;
procedure InitVars;
begin
USBHost_HIDHandler.DeviceInit := @MouseInit;
USBHost_HIDHandler.ReportReceived := @MouseReportReceived;
USBHost_HIDHandlerPtr := @USBHost_HIDHandler;
end;
procedure InitMCU;
begin
InitVars;
USBHost_HIDInit;
USBHost_RegisterDeviceEventHandler(@HIDEventHandler);
USBHost_Init;
// Enable USB device interrupt
IPC7 := DWord(7) shl USBIP0; //for PIC32MX250F128D
//IPC11 := DWord(7) shl USBIP0; //for PIC32MX795F512L
USBIE_bit := 1;
EnableInterrupts;
end;
procedure InitMain;
begin
ANSELA := 0;
ANSELB := 0;
ANSELC := 0;
CVRCON.15 := 0; //cvref off
CVRCON.6 := 0; //disconnect from CVREFOUT
CVRCON.4 := 0; //CVRSRC = AVDD – AVSS
I2C1CON.9 := 1; //I2C1 disable slew rate control (SDO2 silicon bug)
PIC_LED1_Dir := 0;
PIC_LED2_Dir := 0;
end;
begin
Delay_ms(100);
InitMain;
InitMCU;
EnumeratedOK := 0; //reset flag
PIC_LED1 := 1;
PIC_LED2 := 1;
Delay_ms(1000);
PIC_LED1 := 0;
PIC_LED2 := 0;
repeat
USBHost_Main;
//PIC_LED1 := 1;
until False;
end.