Joywarrior JW56FR1 konfigurieren

Dies ist das deutsche Forum für alle Themen um den JoyWarrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
dummzeuch
Posts: 5
Joined: Wed Feb 23, 2011 1:50 pm

Joywarrior JW56FR1 konfigurieren

Post by dummzeuch »

Hallo,

mir wurde gestern ein Joywarrior JW56FR1-MOD auf den den Tisch gelegt und gesagt, ich soll den in unser Programm einbauen, so dass er anstelle des bisher verwendeten JW24F8 bzw. JW24F14 angeschlossen werden kann. (Das natürlich wie immer bis gestern.)

Ich habe es immerhin schon geschafft, das Gerät zu erkennen und Daten einzulesen, die mit denen der Beispiel-Tools übereinstimmen, es hapert allerdings an der Konfiguration.

Sehe ich das richtig, dass man die Konfiguration nur setzen bzw. permanent speichern, nicht jedoch auslesen kann? Oder ist mir da etwas entgangen?

twm
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Joywarrior JW56FR1 konfigurieren

Post by Guido Körber »

Ja, das ist richtig, Rücklesen der Konfiguration ist nicht vorgesehen.
dummzeuch
Posts: 5
Joined: Wed Feb 23, 2011 1:50 pm

Re: Joywarrior JW56FR1 konfigurieren

Post by dummzeuch »

OK, weiter im Text. Laut Doku soll man zum Schreiben der Konfiguration 8 Bytes an das Joystick-Device senden:

--- schnipp ----
4.6
[...]
Setting the sensor parameters is done by sending a eight byte command to the
joystick function:

0 1 2 3 4 5...7
$00 ARng AFilt GRng GFilt $00
--- schnapp ----

Das habe ich getan, aber es hat keine Auswirkungen.

Delphi Code, JoystickDevice ist ein TJvHidDevice aus der JVCL JvHidControllerClass-Unit (von Robert Marquardt):

Code: Select all

function TJw56Fr1.WriteSettings: Boolean;
var
  Buffer: array[0..7] of Byte;
  BytesWritten: DWORD;
  Len: DWORD;
begin
  // egal, was man hier setzt, der Sensor scheint immer +/- 2g-Werte zu liefern
  // das ist für uns prinzipiell OK, da wir sowieos diesen Wertebereich verwenden
  // wollen, aber eigentlich sollte es funktionieren!
  FCachedRange := r56e8G;

  Buffer[0] := $00;
  Buffer[1] := Ord(FCachedRange);
  // LP1 only + 416.5 Hz
  Buffer[2] := $00;
  // Gyro ist uns egal
  Buffer[3] := $00;
  Buffer[4] := $00;
  // 5-7 auf $00
  Buffer[5] := $00;
  Buffer[6] := $00;
  Buffer[7] := $00;

  Len := JoystickDevice.Caps.OutputReportByteLength;

  Result := JoystickDevice.WriteFile(Buffer, Len, BytesWritten)
    and (BytesWritten = Len);
end;
Komischerweise liefert JoystickDevice.Caps.OutputReportBufferByteLength aber nicht 8 sondern 9.

Setze ich Len auf 8, liefert BytesWritten 0, setze ich es auf 9, liefert es 9, also ist vermutlich 9 korrekt.

Nun habe ich mir den Code des ShowData Beispielprogramms genauer angeschaut:

jw56fr1.cpp:

Code: Select all

int jw56fr1_SetParams(HANDLE handle, BYTE ARng, BYTE AFilt, BYTE GRng, BYTE GFilt)
{
	HIDP_CAPS caps = jw_GetHipdCaps(handle);
	BYTE data[JW56FR1_WRITE_SIZE_DEFAULT] = { 0x00 };

	data[0] = 0x00;		//ReportID
	data[1] = 0x00;		
	data[2] = ARng;
	data[3] = AFilt;
	data[4] = GRng;
	data[5] = GFilt;

	return jw_SetData(handle, caps, data);
}
Wobei JW56FR1_WRITE_SIZE_DEFAULT in jw56fr1.h als 9 deklariert ist, was sich mit der Rückgabe von OutputReportBufferByteLength deckt.

Der Beispiel-Code schreibt also nicht 8 sondern 9 Bytes und das erste Byte ist nicht "Command to set the parameters" sondern ein zusätzliches 0-Byte kommentiert als "ReportID". Wenn ich meinen Code entsprechend abändere, funktioniert es.

Code: Select all

function TJw56Fr1.WriteSettings: Boolean;
var
  Buffer: array[-1..7] of Byte;
  BytesWritten: DWORD;
  Len: DWORD;
begin
  Buffer[-1] := $00; // ReportID, immer notwendig

  Buffer[0] := $00; // command
  Buffer[1] := Ord(FCachedRange);
  // LP1 only + 416.5 Hz
  Buffer[2] := $00;
  // Gyro ist uns egal
  Buffer[3] := $00;
  Buffer[4] := $00;
  // 5-7 auf $00
  Buffer[5] := $00;
  Buffer[6] := $00;
  Buffer[7] := $00;

  Len := JoystickDevice.Caps.OutputReportByteLength;

  Result := JoystickDevice.WriteFile(Buffer, Len, BytesWritten)
    and (BytesWritten = Len);
end;
Ich vermute jetzt mal, ich habe da einfach einen Denkfehler und ein "Report" im HID muss zusätzliches zu den Nutzdaten immer ein ReportID-Byte als Prefix enthalten, welches in diesem Fall $00 sein muss. Ist das korrekt? Warum muss das Byte $00 sein?

Ich habe versucht, aus der Microsoft-Doku "Introduction to HID Concepts" (https://docs.microsoft.com/en-us/window ... d-concepts) schlau zu werden, aber die korrekte Verwendung von WriteFile in diesem Zusammenhang ist mir nicht klar, denn die verweist einfach auf die Windows API funktion. Gibt es irgendwo eine leicher verständliche Dokumentation? Gerne auch auf Englisch.
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Joywarrior JW56FR1 konfigurieren

Post by Guido Körber »

Die abweichende Länge ist ein Konstruktionsfehler der Windows USB API. HID Reports können eine ReportID haben, die liegt dann im ersten Byte des Reports, macht also den Report um ein Byte länger. Dabei ist $00 keine gültige ReportID, darf also nicht über den USB gesendet werden. Normalerweise würde man das also so implementieren, dass der Report nur wenn eine ReportID benutzt wird um ein Byte länger ist, so wie es auf der Hardwareebene auch der Fall ist. Microsoft war das schlauer und kappt das 0x00 Byte, der Report hat also auf API Ebene immer eine ReportID und ist dadurch dann um ein Byte länger, wenn er tatsächlich gar keine hat.

Das Datenblatt beschreibt den Sensor natürlich nicht im Kontext der Microsoft API, sondern allgemeingültig.
dummzeuch
Posts: 5
Joined: Wed Feb 23, 2011 1:50 pm

Re: Joywarrior JW56FR1 konfigurieren

Post by dummzeuch »

Gut, damit komme ich weiter. Danke!
Post Reply