Posts by fs-support_HK

    Ich hätte einen möglichen Ansatzpunkt, wo eventuell in diesem Testprogramm etwas schief gehen könnte.


    Sie verwenden für SCHEDULE und GET_RESULT immer das gleiche Message-Header-Array msg_read_awg[], ohne dessen Inhalt jemals wieder aufzufrischen. Es wird nur zu Beginn des Programms global initialisiert. Der chFlags-Eintrag ist aber nicht nur ein Ausgangsparameter, sondern auch ein Eingangsparameter. Das heißt die Übertragung verhält sich anders, wenn bei chFlags der Wert 0 oder 1 übergeben wird. Und zwar genau dahingehend, ob die NetDCU beim Empfang das letzte Byte der Übertragung mit ACK quittiert oder nicht.


    Sie beginnen mit chFlags=0. Das heißt die NetDCU quittiert das letzte Byte beim Empfang *nicht*. Aber vermutlich sendet die Gegenstelle bei allen Bytes brav ein ACK, weshalb nach dem ersten Zyklus nun chFlags auf 1 steht. Da Sie diesen Wert nirgends zurücksetzen, wird nun im nächsten SCHEDULE auch mit chFlags=1 gearbeitet. Das heißt ab nun quittiert auch die NetDCU das letzte empfangene Byte mit ACK.


    Ich vermute nun, dass in einer Übertragung Ihr AWG irgendwann einmal beim letzten Byte kein ACK gesendet hat, vermutlich weil das Byte nicht ordentlich dort ankam. Dies wird nun mit chFlags=0 quittiert, so dass im nächsten Zyklus die NetDCU das letzte Byte nun wieder nicht mehr quittiert. Dies ist nun vermutlich der fehlerhafte Zyklus, den Sie sehen. Möglicherweise sehen Sie in Ihrem Oszilloskop-Bild aber gar nicht so weit zurück, dass Sie den tatsächlich fehlerhaften vorangegangen 6-Byte-Zyklus noch sehen, sondern nur den aktuellen, der Ihre fehlerhaften Daten enthält.


    Mein Vorschlag wäre darum, entweder für GET_RESULT ein anderes Array als bei SCHEDULE zu verwenden. Oder das Array in jedem Durchlauf vor dem SCHEDULE wieder neu vorzubelegen.


    Vielleicht sollten Sie mal darauf achten, ob in chFlags ab und zu unterschiedliche Werte (0 oder 1) zurückkommen. Bisher löst dies in Ihrem Testprogramm wegen Abfrage auf >1 noch keine unterschiedliche Behandlung oder gar einen Fehler aus. Auch wäre es interessant, was tatsächlich im Fehlerfall in chFlags stand, also welcher Fehler konkret auftrat. Und hier wäre wie gesagt auch der vorangegangene Zyklus noch interessant.


    Mit freundlichen Grüßen,


    H. Keller

    Quote from "all-finder"

    Wie kann man der Anwendung Parameter mitgeben?


    Ist es nicht sinnvoller, die Parameter selbst irgendwo in der Registry abzulegen und dann in der Anwendung dort nachzuschauen? Denn um Parameter in init zu ändern -- angenommen dies ginge überhaupt -- müsste man ja auch die Registry ändern.


    Mit freundlichen Grüßen,


    H. Keller

    Kann es sein, dass es einfach an der Reihenfolge der Includes liegt? Oder an einem anderen Include, das selbst schon winsock.h einbindet und wenn dann noch zusätzlich winsock2.h eingebunden wird, kommt es zu den Mehrfachdefinitionen, die beanstandet werden? Was zum Beispiel bindet stdafx.h alles ein?


    Mit freundlichen Grüßen,


    H. Keller

    Mal eine etwas ketzerische Frage: ich habe mich immer gefragt, was heißt eigentlich: "Both levels and both edges"? Wäre es nicht einfacher zu sagen "Always"? Denn offensichtlich führt doch jeder Zustand des Pins zu einem Interrupt.


    H. Keller

    Quote from "all-finder"

    Jedoch auch mit der Marshal - Funktion wird Fehler 87 zurückgegeben, da der value - Wert (Rückgabe der Read-Funktion) immer gleich 0 ist. Kann ich dies ignorieren?


    Nein. Wenn 0 zurück kommt, heißt es, dass ein Fehler aufgetreten ist. Ich vermute es liegt am


    uint lpNumberOfBytesRead


    in der Deklaration von ReadFile(). Ändern Sie das mal auf


    out uint lpNumberOfBytesRead


    ab. Es muss an dieser Stelle nämlich ein Pointer übergeben werden. Über out wird aus dem Value-Parameter ein Reference-Parameter, also indirekt ein Pointer. Nebenbei müssen Sie den Wert dann nicht mehr vorbelegen.


    Mit freundlichen Grüßen,


    H. Keller

    Quote from "jmata"

    As I found in the documentation, the NetDCU8’s pins for the bus I2C are J5 connector pin 10 (SDA) and 11 (SCL). They are GPIO.


    Most of the pins of a microcontroller can support different possible functions. Therefore you can use these pins 10 and 11 for either GPIO purposes, or as dedicated I2C. Other pins can support other functions. If you use pins 10 and 11 for I2C, you have to exclude them from any access of any other drivers. Especially if you also use the DIO driver, you must set the corresponding bits of UseAsIo to zero (see DIO docu).


    If you want to use NI2C, then these two pins are the only possibility to build the I2C bus. If you use the I2C over GPIO driver, then you can use any pair of GPIO pins on J5 to build an I2C bus, not only pins 10 and 11. This may be useful if you have many many I2C devices to connect and you need more than one I2C bus. If you just want to connect the above TPIC2810 device, I would recommend using NI2C and the commands given in my last posting.


    Regards,


    H. Keller

    Genau, Sie müssen GND schalten. Die Pins sind unbeschaltet auf High und müssen durch den Taster auf Low gelegt werden.


    Und noch eine weitere Anmerkung: Der Aufruf der Funktion GetLastError() liefert in C# nicht unbedingt den tatsächlichen Fehler der zuvor aufgerufenen Funktion. Der Grund ist, dass die .NET-Umgebung selbst auch Win32-Aufrufe macht und falls zwischenzeitlich ein solcher Aufruf erfolgt ist, was man nie ausschließen darf, wird *dessen* Ergebnis geliefert. Korrekt ist daher, die Funktion


    Marshal.GetLastWin32Error()


    aufzurufen. Wird ein DllImport aufgerufen, der SetLastError=True hat, dann wird automatisch bei der Rückkehr schon der GetLastError()-Wert abgerufen und gemerkt. Marshal.GetLastWin32Error() liefert dann den gemerkten Wert zurück, der somit auch wirklich zum entsprechenden Aufruf passt.


    Mit freundlichen Grüßen,


    H. Keller

    Quote from "jmata"

    The message headers structure are like this in the NetDCU8 device:
    - byte chDevAddr, byte chFlags, ushort wLen.


    But I want to comunicate by I2C to a texas instruments TPIC2810 device wich respond to the following needs:
    - byte slave address, byte subaddress.
    - byte data to slave


    How can I specify the subaddress? Should I pass byte chFlags like byte subaddress?


    This is just a problem of the used terms. If you say "Command" instead of "Subaddress", then it is easier to understand. When you look at the TPIC2810 data sheet at page 13, you find an explanation. The subaddress is just a data byte you have to send to the device, specifying what you want to do. Depending on this command byte you can send a value, read a value or just tell the device to switch something.


    As address, you have to give G3 G2 G1 G0 A2 A1 A0 where G3 G2 G1 G0 is fix as 1 1 0 0 and A2 A1 A0 can be set by the appropriate pins of the device. Let's assume you have connected A2..A0 to GND, then the address is binary 1100 000. As last bit you have to append 0 for write and 1 for read. This brings us to the value of 0xC0 for writing to the device and 0xC1 for reading from the device. The possibility to modify A2..A0 allows for up to 8 of these TPIC2810 devices on one I2C bus. If each of them has a different combination of A2..A0, you can address each of these devices on its own address. C0/C1 for the first device, C2/C3 for the second device, and so on until CE/CF for the eighth device.


    Now the different commands, the so called "subaddresses". This is explained on the next page, page 14. To write a value you have to send byte 0x11 and the value as second byte. Therefore from the view of the NI2C driver, you have to send two bytes of data in one message. This results in something like this, where XX is the data you want to send.


    Code
    1. NI2CFile.NI2C_MSG_HEADER[] writeop =
    2. new NI2CFile.NI2C_MSG_HEADER[]
    3. {
    4. new NI2CFile.NI2C_MSG_HEADER(0xC0, 0x00, 0x0002) // Send 2 bytes
    5. };
    6. byte[] writedata = {0x11, 0xXX};
    7. ni2c.Schedule(writeop, writedata);
    8. ni2c.GetResult(writeop, writedata);


    After the last command, you can check writeop[0].chFlags for errors during transmission.


    The same format holds for command 0x44, just modify the writedata array. If you want to use command 0x22, change the wLen entry from 2 to 1 and prepare a writedata array with just the one byte 0x22.


    To read the value, you have to send one byte 0x11 to the device as one message. Then as a second message, you have to read one byte from the device. Here you have to prepare two messages with each one byte for the NI2C, one send, one receive.


    Code
    1. NI2CFile.NI2C_MSG_HEADER[] readop =
    2. new NI2CFile.NI2C_MSG_HEADER[]
    3. {
    4. new NI2CFile.NI2C_MSG_HEADER(0xC0, 0x00, 0x0001), // send 1 byte
    5. new NI2CFile.NI2C_MSG_HEADER(0xC1, 0x00, 0x0001) // receive 1 byte
    6. };
    7. byte[] readdata = {0x11, 0x00};
    8. ni2c.Schedule(readop, readdata);
    9. ni2c.GetResult(readop, readdata);


    Here, readdata[1] is just a dummy value and will be filled in by the transmission. After this code, you can check readop[0].chFlags and readop[1].chFlags for any errors in the transmission. If everything is OK, you have the result , i.e. the byte that was read in readdata[1].


    If you don't want your data to be overwritten in GetResult(), you can use different arrays there. However you have to make sure that they have exactly the same size as readop[] and readdata[] that you use in Schedule().


    Regards,


    H. Keller

    Ich verstehe die Frage nicht ganz. Wo drücken Sie denn das 'S' wenn nicht in einem DCUTermi?


    Um in den Bootloader zu kommen, muss das 'S' natürlich über COM1: zur NetDCU gesendet werden und dort kommen auch die Rückmeldungen. Das hat mit einem Display nichts zu tun.


    Mit freundlichen Grüßen,


    H. Keller

    Quote from "gunther"

    3. Wenn ich den Trigger von steigender Flanke auf fallende Flanke (Registry) ändere, dann habe ich KEINE zusätzlichen Aufrufe meines IST mehr! Dies ist auch unabhängig von der Art des Interruptsignals.


    Was ja nun kein Widerspruch ist. Angenommen, Sie haben jeweils beim Umschalten einen 1V Überschwinger. Betrachten wir die beiden Fälle:


    Umschalten high->low:
    Das Signal geht auf 0V, aber der Überschwinger hebt es anschließend nochmal auf 1V an. Ein Low-Level wird aber nur bis maximal 0.8V erkannt. Das heißt der Prozessor erkennt dies eventuell schon wieder als steigende Flanke und löst einen neuen Interrupt aus.


    Umschalten low->high:
    Das Signal geht auf 3.3V, der Überschwinger senkt es anschließend nochmal auf 2.3V. Ab 2.0V wird aber eindeutig ein High erkannt. Das heißt das Signal ist definiert und kontinuierlich logisch 1, es wird definitiv *kein* neuer Interrupt ausgelöst.


    Insofern können Sie sehr wohl ein unterschiedliches Verhalten je aktivierter Interruptflanke haben.


    Quote

    Egal ob ich auf fallende od. steigende Flanken triggere kann ich beobachten, daß einige Interruptsignale KEINEN Aufruf des IST erzeugen (ist auch im Kernel Tracker zu sehen).


    Sieht man im Kernel Tracker, ob zu diesem Zeitpunkt ein anderer Thread am Laufen ist? Es könnte sein, dass ein nicht-unterbrechbarer Systemthread läuft, beispielsweise ein Flash-Zugriff.


    Wie auch immer, ich werde mir die Sache mal noch etwas genauer anschauen. Vielleicht finde ich da ja noch was.


    Mit freundlichen Grüßen,


    H. Keller

    Quote from "Rad"

    How can I detect power fail?


    This can only be done by some external circuitry.


    Quote

    After detecting "power fail" how much time I have to save my application status?


    The first thing that should happen, for example by an interrupt procedure, is to switch off any power hungry devices, e.g. the display and especially the display backlight. Then you can store your data in a file on the flash disk.


    The amount of time that you have depends on the type of your power supply. For example if you add some capacities or accumulators, you can extend the time before power breaks down completely to several seconds..


    Regards,


    H. Keller

    Hmm, das Problem ist nicht so einfach. Im Prinzip wird bei einem Treiber, der in einer Applikation geöffnet ist, die vorzeitig abgebrochen wird, kurz vor dem Abbruch nochmal DeviceIoControl() mit IOCTL_PSL_NOTIFY aufgerufen. Das könnte der Treiber entsprechend nutzen, solche Dinge wie den hier allozierten Interrupt wieder freizugeben. Leider scheint dies bei dem DIO-Treiber nicht so implementiert zu sein.


    Insofern ist die von Ihnen genannte Methode zwar nicht so wirklich befriedigend, aber zumindest für die Testphase praktikabel. Ich denke dass bei gleicher Ausgangskonfiguration auch immer der gleiche SYS_INTR zurückgeliefert wird. Die 28 müsste insoweit eigentlich passen. Die Zahl kann sich aber ändern, wenn Sie z.B. einen weiteren Treiber benutzen und dort zuvor auch einen Request für einen Interrupt machen.


    Ich vermute am Ende wird Ihre Applikation ja sowieso dauerhaft laufen, vom Einschalten bis zum Ausschalten des Boards. Da gibt es dieses Problem dann ja nicht mehr.


    Mit freundlichen Grüßen,


    H. Keller

    Die Eingänge der NetDCU sind sehr hochohmig. Kann es sein, dass das Signal bei der fallenden Flanke prellt? Dass also ein Überschwinger im Signalverlauf dazu führt, dass die NetDCU doch eine steigende Flanke erkennt? Gerade mit einem Oszilloskop müsste man sowas vielleicht erkennen können (Zeit auf wenige ns runterdrehen).


    Die Verarbeitung der Interrupts ist immer gleich. Da gibt es keinen Unterschied bei steigender oder fallender Flanke. Das entsprechende Interruptregister des Prozessors wird initialisiert und dann kommen eben die Interrupts. Ich würde darum vermuten, dass der Prozessor tatsächlich in diesen fehlerhaften Fällen eine steigende Flanke sieht.


    Ich bin nun nicht der große Hardware-Experte, aber vielleicht hilft ein Busabschluss oder ein Kondensator (Tiefpass) auf der Eingangsleitung?


    Mit freundlichen Grüßen,


    H. Keller

    Die Standard-Implementierung in Windows CE für den entsprechenden ARM-Prozessor ist relativ ineffizient programmiert. Wir haben den Treiber darum vor ein paar Monaten komplett überarbeitet, ja mehr oder weniger neu geschrieben. Seitdem ist das ganze Verhalten deutlich besser. Ich habe es seitdem noch nicht "geschafft", bei 115kbit/s auch nur ein Byte zu verlieren. Arbeitet man auf einem Port sogar bidirektional, dann kriege ich mit der PicoMOD sogar meinen PC, immerhin ein recht flotter Pentium D, in die Knie.


    Für diesen Treiber wenden Sie sich bitte an unsere Verkaufsabteilung.


    Mit freundlichen Grüßen,


    H. Keller

    It is not impossible, but very unlikely that a board that is already running on one OS version is converted to a new OS version. As we are always designing new boards, like the NetDCU9 and NetDCU10 earlier this year, we concentrate on porting the new OS versions to the new boards. Therefore you'll have to wait for new PicoMOD boards to arrive in the future. Like the NetDCU series, PicoMOD will grow to a full family of boards, supporting different hardware features and OS versions then.


    Is there a special reason why you want to have WinCE6.0?


    Regards,


    H. Keller

    We have created new categories for NetDCU5.2, NetDCU6, the DCULx series and general questions not regarding specific hardware or software. As the Windows CE sub-categories were also valid for the PicoMOD series, they were moved from the NetDCU section to a seperate main category.


    We hope this represents a clearer arrangement and we eagerly await your first topics in the new categories.


    Regards,


    H. Keller

    Well, probably the initialisation of the display is done in the boot monitor, not in windows (see commands XDI and XDE in boot loader EBoot). A restart probably only restarts windows, but does not repeat the initialisation steps of the boot loader. Therefore the display remains dark.


    Regards,


    H. Keller