Home Entwicklung des Treibers QADC Fehlersuche Hardware Poti-Wert wird in Software sichtbar
 

3.6 Untersuchung des Completion Flag

(05.07.2005)

Nachdem grundsätzlich das Beschreiben von QADC-Registern mit dem Beispielcode (siehe Ende der Beschreibung im Abschnitt zuvor) funktionierte, wagte ich schon erste Experimente mit dem Auslesen des Statusregisters.

Grundsätzliche erste Idee ist:

  • Messung starten mittels Setzen des "SSE1"-Bits mittels des Befehls adcreg->cr1.b.SSE1 = 1;
     
  • Das Completion-Flag pollen mittels des Ausdrucks adcreg->sr0.b.CF1. Dieser Ausdruck ist in der Routine void qadc_debug_print_status(long l_i_scan) versteckt.
     
  • Das Pollen geschieht im ersten Test mittels einer Schleife, die fix nach einer bestimmten Anzahl von Zyklen stoppt. Hier die Codezeile der Schleife: for(l_i_scan=9L; l_i_scan>0L; l_i_scan–)
     

Der gesamte Code sah für dieses Experiment folgendermaßen aus:

static int qadc_open(struct inode *inode, struct file *file)
{
/* Testcode!: */

    short *qadcmcr = (short *)QADCMCR;
    short *ccw = (short *)CCW_TABLE_START;
    short value1, value2;
        long l_i_scan;

    value1 = *qadcmcr;
        qadc_debug_print_status(1L);
    printk(KERN_NOTICE "Adress of QADCMCR: %lx ; value inside QADCMCR before writing: %x \n",(long)qadcmcr, value1);
    printk(KERN_NOTICE "Adress of adcreg->mcr: %lx ; value inside adcreg->mcr before writing: %x \n",
                       (long)&adcreg->mcr, adcreg->mcr.w);
        /* The QADC64 Module configuration register. */

        adcreg->mcr.b.STOP = 1;         /* Disable the QADC64 (Reset of QADC)*/
        qadc_debug_print_status(2L);
        adcreg->mcr.b.STOP = 0;         /* Enable the QADC64 */
        adcreg->mcr.b.FRZ = 0;          /* Ignore the freeze bit */
        adcreg->mcr.b.SUPV = 0;         /* allow user access */
        qadc_debug_print_status(3L);
    printk(KERN_NOTICE "After Setting: Adress of adcreg->mcr: %lx ; value inside adcreg->mcr before writing: %x \n",
                       (long)&adcreg->mcr, adcreg->mcr.w);

    printk(KERN_NOTICE "open: ccw=%lx curent value at ccw[0]: %x\n",(long)ccw, ccw[0]);
    value1 = (IST_QCLKx16<<IST_BITPOS) | (CHAN_PQB0<<CHAN_BITPOS);
    value2 = (IST_QCLKx16<<IST_BITPOS) | (CHAN_END_OF_QUEUE<<CHAN_BITPOS);
    printk(KERN_NOTICE "I will write to ccw[0]: %x and ccw[1]: %x\n",value1, value2);
    ccw[0] = (IST_QCLKx16<<IST_BITPOS) | (CHAN_PQB0<<CHAN_BITPOS);
    ccw[1] = (IST_QCLKx16<<IST_BITPOS) | (CHAN_END_OF_QUEUE<<CHAN_BITPOS);
        qadc_debug_print_status(4L);

        adcreg->cr1.b.MQ1 = 0x01;       /* Software-triggered single-scan mode (started with SSE1) */
        qadc_debug_print_status(55L);

        adcreg->cr1.b.SSE1 = 1;         /* single-scan started! */
        qadc_debug_print_status(66L);
        qadc_debug_print_status(77L);

        for(l_i_scan=9L; l_i_scan>0L; l_i_scan--)
        {
                value1 = l_i_scan%2;
                if(value1==0)
                {
                        qadc_debug_print_status(l_i_scan);
                }
        }
        printk(KERN_NOTICE "After loop: l_i_scan: %ld, l_i_scan%%4: %d \n", l_i_scan, value1);

/* Testcode!: End */

Dieser Code führte dann zu folgendem Output:

/usr> ./readqadc-1_0
i: 1, SR0: ffff8001, CF1: 1
Adress of QADCMCR: 40190000 ; value inside QADCMCR before writing: 0
Adress of adcreg->mcr: 40190000 ; value inside adcreg->mcr before writing: 0
i: 2, SR0: 0, CF1: 0
i: 3, SR0: 0, CF1: 0
After Setting: Adress of adcreg->mcr: 40190000 ; value inside adcreg->mcr before writing: 0
open: ccw=40190200 curent value at ccw[0]: c0
I will write to ccw[0]: c0 and ccw[1]: ff
i: 4, SR0: 0, CF1: 0
i: 55, SR0: 0, CF1: 0
i: 66, SR0: 200, CF1: 0
i: 77, SR0: ffff8001, CF1: 1
i: 8, SR0: ffff8001, CF1: 1
i: 6, SR0: ffff8001, CF1: 1
i: 4, SR0: ffff8001, CF1: 1
i: 2, SR0: ffff8001, CF1: 1
After loop: l_i_scan: 0, l_i_scan%4: 1
qadc released
Hier soll der QADC ausgelesen werden
Adresse pdev: 6b4a44
Der Rueckgabewert von open lautet: 3
 Das Device wurde wieder geschlossen!
pid 48: failed 34048
/usr>

Etwas überraschend ist die Geschwindigkeit, mit welcher das CF1 gesetzt wird. Allerdings irritiert auch, warum alle anderen Flags auch gesetzt werden.

Eine genauere Überlegung zeigt, daß der Output von void qadc_debug_print_status(long l_i_scan) noch nicht richtig funktioniert hat. Bitte die "ffff" überlesen! Wichtig ist bei der Marke i: 66 die 200. Diese sagt, daß das Bit QS9 gesetzt ist. Das Bit QS9 zeigt für die Queue 1 an, daß "Queue 1 active, queue 2 idle" ist. Das stimmt auch nach dem Setzen des SSE1-Bit. Bei der Marke i: 77 steht dann im Register der Wert 8001. Das heißt, daß das CF1 gesetzt ist und der Pointer auf die CCW-Tabellen auf dem nächsten und hier letzten Tabelleneintrag CCW[1] steht.

Also funktioniert alles wunderbar.

Diesen Stand habe ich jetzt als endgültigen Versionsstand 1_0 gesichert. Jetzt geht es weiter mit qadc-1_1.c als neues Testfile.


Copyright © Andreas Birkert
Letzte Aktualisierung am 20. Dezember 2013
Home Entwicklung des Treibers QADC Fehlersuche Hardware Poti-Wert wird in Software sichtbar