Hallo liebe Community,
ich schreibe momentan meine Bachelorarbeit und verwende dafür einen PMW
3310 Gamingmaus-Sensor. Es geht darum kleine Längenänderungen zu messen.
Da die Längenänderungen sehr klein sein sollen, benötige ich auch die
höchste Auflösung von 5000 dpi.
Ich verwende als IDE Eclipse. Als Controller dient ein STM32L476.
Die Kommunikation über SPI funktioniert wunderbar. Ich kann alle
Register auslesen und auch beschreiben. Möchte ich allerdings das
Register mit dem entsprechenden Wert (0x64) für die höchste Auflösung
beschreiben, so steht im Register nach anschließendem Auslesen nur der
Wert 0x32. Pixart meinte auf Anfrage, dass ich die im Anhang befindliche
Firmware in den Sensor übertragen muss. Dabei handelt es sich um ein
ASCII textfile. So müsste ich also diese Daten über SPI in den Sensor
übertragen.
Kann mir vielleicht jemand helfen und hat eine Idee, wie man das machen
könnte? Ich habe auch schon ein, zwei Sachen ausprobiert. Nur leider
ohne Erfolg.
Vielen Dank und liebe Grüße
Register 0x64 beschreiben kannst du auch nicht. Das ist rein
Read-Only-Register.
Was sollen die Configuration A-D sein? gibt es noch ein anderes
Datasheet?
Johannes R. schrieb:> Pixart meinte auf Anfrage, dass ich die im Anhang befindliche> Firmware in den Sensor übertragen muss. Dabei handelt es sich um ein> ASCII textfile. So müsste ich also diese Daten über SPI in den Sensor> übertragen.
Vermutlich nachdem du eine Wandlung HEX -> Binär durchgeführt hast.
> Kann mir vielleicht jemand helfen und hat eine Idee, wie man das machen> könnte?
Da wirst du Pixart fragen müssen. Das Datenblatt gibt nicht her, wie man
einen Firmware-Download macht. Ohne diesen Teil des Puzzles stocherst du
im Nebel.
Das ASCII Textfile einfach in deinen Sourcecode kopieren, und folgendes
drumherumbauen:
1
constchar*image={
2
0x03,
3
0x11,
4
0xb1,
5
0xc2,
6
0xc6,
7
...
8
};
Das geht sehr gut per Block Edit. "const" nicht vergessen, sonst landet
der Kram im RAM. Grösse bekommst per sizeof(). Dann durch den SPI (ggf.
DMA) in den Sensor klappern.
VG,
/th.
Random .. schrieb:> Grösse bekommst per sizeof().
Aber nur wenn man das Array mit "const char image [] = { ... };" anlegt
statt mit "const char* ...", sonst erhält man lediglich die Größe von
Pointern.
Vielen Dank erstmal für die vielen Hinweise!
Ich hätte schon vorher schreiben sollen, was ich versucht hatte.
Entschuldigung dafür!
Ich hatte zuerst die ASCII-Werte in MATLAB geladen und sie in
Dezimalwerte umgewandelt (ob dies nun sinnvoll ist oder nicht sei
erstmal dahin gestellt - in jedem Fall sollte das doch eigentlich
funktionieren). MATLAB hat auch die Zeilenumbrüche mit in Dezimalzahlen
umgewandelt, wobei dann sowas hier entstand:
Aus diesem Ausschnitt (ASCII)
03
11
b1
wurde dann(dezimal):
48
51
13
10
49
49
13
10
98
49
13
10
Die 13 und die 10 wiederholen sich also immer (Umbrüche). Die habe ich
dann entfernt und eine Reihe von Dezimalzahlen erhalten.
Daraus habe ich dann ein Array gebastelt und in meinen Code eingefügt
(siehe Anhang: srom.c)
Dann folgte meine routine um die Daten an den chip zu übertragen.
1
// write 0x1d to SROM_Enable register
2
sendData(0x13,0x1d);//(address, data)
3
HAL_Delay(1);
4
5
//write 0x18 to SROM_Enable register to start SROM Download
6
sendData(0x13,0x18);//(address, data)
7
HAL_Delay(1);
8
9
10
chipSelect();//chipselect -> CS low to select PMW3310
Die geforderte Prozedur dafür ist im .png im Anhang zu sehen
Wenn die Übertragung der Firmware erfolgreich war, kann das Register
"SROM_ID" (0x2a) ausgelesen werden. Wenn es erfolgreich war, steht dort
die Firmware-nummer drin, sonst 0x00. Bei mir steht danach leider nur
0x00....
Übrigens: die langen delays von 1ms sind natürlich zu lang. Eine
Funktion o.ä. die kürzere delays kann muss ich erst noch implementieren;
sollte doch aber eigentlich trotzdem damit funktionieren.
bla schrieb:> Register 0x64 beschreiben kannst du auch nicht. Das ist rein> Read-Only-Register.>> Was sollen die Configuration A-D sein? gibt es noch ein anderes> Datasheet?
0x64 sollte der maximale Wert für die höchste Auflösung sein (siehe
Anhang).
Mit den config A-D kann man den chip konfigurieren: Auslösung,
Angle_snapping an/aus, Winkel einstellen für angle_tune usw.
Johannes R. schrieb:> Aus diesem Ausschnitt (ASCII)>> 03> 11> b1>> wurde dann(dezimal):>> 48> 51> 13> 10> 49> 49> 13> 10> 98> 49> 13> 10
\o/
Sinnhaftigkeit braucht nicht weiter diskutiert zu werden.
Johannes R. schrieb:> Aus diesem Ausschnitt (ASCII)>> 03> 11> b1>> wurde dann(dezimal):>> 48> 51> 13> 10> 49> 49> 13
Das war ASCII (Character) und bleibt ASCII (Darstellung in Dezimal). Was
gefordert ist, ist eine Umwandlung ASCII ZU HEX.
Dann wird aus
03 —> HEX 0x03 —> DEZ 3
11 —> HEX 0x11 —> DEZ 17
B1 —> HEX 0xB1 —> DEZ 177
Wenn du Buße für deinen Fauxpas machen möchtest, könntest du einfach
deinen Header
#include <inttypes.h>
#include "srom.h"
uint8_t SROM[]= {
an den Anfang der originalen Datei setzen und dann 3000x ein „0x“ an den
Anfang jeder folgenden Zeile und ein Komma an das Ende setzen (nicht
beim letzten Eintrag). Dann ist alles fertig.
Harald schrieb:> Wenn du Buße für deinen Fauxpas machen möchtest, könntest du einfach> deinen Header> #include <inttypes.h>> #include "srom.h">> uint8_t SROM[]= {>> an den Anfang der originalen Datei setzen und dann 3000x ein „0x“ an den> Anfang jeder folgenden Zeile und ein Komma an das Ende setzen (nicht> beim letzten Eintrag). Dann ist alles fertig.
Vielen dank nochmal für den Hinweis. Das habe ich gemacht (siehe
Anhang). Leider bleibt alles beim Alten..... :(
Nach dem letzten Byte hast ja DOCH ein Komma... aber das dürfte den
Fehler nicht auslösen, weil Du im Source eine feste Größe angibst.
Warum werden aber 6140Bytes gesendet und wieso veroderst du jedes Byte
mit 0x80. Das kann nicht richtig sein.
for(int i=0; i<6140; i++)
{
data = (SROM1[i] | 0x80);
Ansonsten bitte einen LogicAnalyzer besorgen (HW kostet <10€), dazu die
Software SIGROK. Dann kannst du sehen, was tatsächlich gesendet wird und
ob das zum Datenblatt passt.
Sehe gerade, der Rest des Source (also vor der Hauptschleife) ist auch
total falsch.
sendData(0x13, 0x1d); //(address, data)
HAL_Delay(1);
Warum hier sendData??? Unten wird HAL_SPI_Transmit verwendet...
//write s of SROM_LOAD_BURST register
uint8_t SROM_LOAD_BURST_add = (0x62| 0x80);
Warum 0x80???
//transmit data over SPI (address)
HAL_SPI_Transmit(&hspi1, &SROM_LOAD_BURST_add, 1, HAL_MAX_DELAY);
Was soll das bewirken?
Ja richtig, hab im Eifer des Gefechtes vergessen das Komma hinter dem
letzen byte zu löschen .... schon erledigt.
1
for(inti=0;i<6140;i++)
Die Zahl 6140 stammt noch von meinem falsch umgewandelten ascii-file.
Die sendData-Funktion übermittel Daten an ein bestimmtes Register.
Darain enthalten ist auch das
Auch hier taucht wieder der ODER-Verknüpfung mit 0x80 auf. Der Sensor
weiß, dass Daten SENDEN soll, wenn das MSB eine "0" ist. Dass er Daten
EMPFANGEN soll sagt man ihm, indem das MSB auf "1" gesetzt wird.
Deshalb sage ich ihm hier, dass das MSB der Adresse eine "1" ist und er
Daten empfangen soll:
Es hat jetzt funktioniert!!!
Ich hatte nach dem Übertragen der Firmware noch eine Funktion vergessen
zu deaktiviren, die den Chip resettet. Beim Auslesen der Register war
dann natürlich nicht der Erfolg zu sehen.
Dank eurer Hinweise zu meiner ASCII-HEX-Verwirrung, hat es dann also
funktioniert.
Vielen Dank für die Unterstützung.