Ich versuche spaßeshalber mal über das KatCE Board mit mit 68010 und
68230
am Port B des 68230 die Daten eines DHT11 einzulesen .. und der Kram ist
scheinbar zu langsam. Die CPU wird mit 10,240 Mhz getaktet.
Due Hauptursache für mein Problem ist die Implementation der
Ein-Ausgabefunktionen des verwendeten FBuG Monitors.
der PIT liegt auf ungeraden Adressen
1
#define PIT_PGCR 0x400001
2
#define PIT_PSRR PIT_PGCR+2 /* 0x400003 */
3
#define PIT_PADDR PIT_PSRR+2 /* 0x400005 */
4
#define PIT_PBDDR PIT_PADDR+2 /* 0x400007 */
5
#define PIT_PCDDR PIT_PBDDR+2 /* 0x400009 */
6
#define PIT_IVR PIT_PCDDR+2 /* 0x40000B */
7
#define PIT_PACR PIT_IVR+2 /* 0x40000D */
8
#define PIT_PBCR PIT_PACR+2 /* 0x40000F */
9
#define PIT_PADR PIT_PBCR+2 /* 0x400011 */
10
#define PIT_PBDR PIT_PADR+2 /* 0x400013 */
11
#define PIT_PAAR PIT_PBDR+2 /* 0x400015 */
12
#define PIT_PBAR PIT_PAAR+2 /* 0x400017 */
13
#define PIT_PCDR PIT_PBAR+2 /* 0x400019 */
14
#define PIT_PSR PIT_PCDR+2 /* 0x40001B */
15
#define PIT_TCR PIT_PSR+6 /* 0x400021 */
16
#define PIT_TIVR PIT_TCR+2 /* 0x400023 */
17
#define PIT_CPRH PIT_TIVR+4 /* 0x400027 */
18
#define PIT_CPRM PIT_CPRH+2 /* 0x400029 */
19
#define PIT_CPRL PIT_CPRM+2 /* 0x40002B */
20
#define PIT_CRH PIT_CPRL+4 /* 0x40002F */
21
#define PIT_CRM PIT_CRH+2 /* 0x400031 */
22
#define PIT_CRL PIT_CRM+2 /* 0x400033 */
23
#define PIT_TSR PIT_CRL+2 /* 0x400035 */
und ich benutze die für 8 Bit Eingaben vorgesehene Funktion get8().
1
get8(addr)/* returns 8 bits not sign-extended */
2
intaddr;
3
{
4
externintasmaddr;
5
externintasmdata;
6
7
asmaddr=addr;
8
asmget8();
9
asmdata=asmdata&MASK8;
10
return(asmdata);
11
}
die ihrerseits asmget8() aufruft
1
asmget8: clr.l asmdata
2
mov.l %a0,-(%sp)
3
mov.l asmaddr,%a0
4
mov.b (%a0),asmdata+3
5
bpl.b nosi8
6
or.l &0xffffff00,asmdata
7
nosi8: mov.l (%sp)+,%a0
8
rts
Das dauert ja regelrecht Wochen bis die CPU da durch ist.
In der einfachen Lesefunktion für den DHT11 habe ich zwischen 2 Abfragen
eine Verzögerung von ca. 40 mikrosekunden einzuhalten:
1
...
2
while(!get8(PIT_PBDR)&0x01);// wait for high "response"
3
while(get8(PIT_PBDR)&0x01);// wait for low "Bit 0 Start"
4
for(b=0;b<3;b++)
5
{
6
num=0;
7
for(i=0;i<8;i++)
8
{
9
while(!get8(PIT_PBDR)&0x01);// wait for L/H
10
__asmvolatile("nop");
11
__asmvolatile("nop");
12
if(get8(PIT_PBDR)&0x01)// read Data
13
num|=1<<(7-i);
14
while(get8(PIT_PBDR)&0x01);// wait for H/L
15
}
16
bitbuf[b]=num;
17
}
18
...
Ich bin mit Assembler beim 68k nicht sonderlich bewandert, hat hier
einer der Profis eine Idee wie ich das Verfahren für diesen speziellen
Fall der Abfrage nur des Pins PB0 des PIT entscheidend beschleunigen
kann?
Wenn es gar nicht geht muß ich halt die ganze Leseroutine in Assembler
einfügen, allerdings muß ich da erst wieder viel lesen, ich wußte vor
Jahren schon mal besser Bescheid :-(
Gruß,
Holm
Welcher Scherzkeks hat diesen Asm-Code verbrochen? Frischer PIC
Konvertit? Auf einer 68K CPU Funktionsaufruf mit Übergabe von Parameter
und Returnwert via globaler Variable? Und die (bekloppte)
Vorzeichenerweiterung ist auch reichlich aufwändig geraten.
Rufus Τ. Firefly schrieb:> Und was geschieht, wenn Du auf die Assemblerkiste verzichtest?> uint8_t wert;>> wert = *((volatile uint8_t *) addresse);
Das würde ich in erster Instanz auch probieren (noch 'n volatile dazu),
ansonsten (wenn's denn unbedingt Assembler sein soll) mal eben aus der
Hüfte geschossen (und ungetestet):
1
#define pit_ready() __extension__({ \
2
char res = 0; \
3
__asm__ __volatile__(\
4
" .equ PIT_PBDR,0x400013 \n\t" \
5
" move.b PIT_PBDR,%[res] \n\t" \
6
: [res] "=r" (res) \
7
: /* no input */ \
8
: /* no clobber */ \
9
); \
10
res; \
11
})
Speziell für die etwas schräge Anbindung von 16 bit Peripherie an den
32-Bit Bus hat der 68k den movep-Befehl. Der wird aber erst interessant,
wenn Du mehrere Register auf einmal holen willst.
@rufus:
Es gibt aber Alignment-restriktionen die mir derzeit nicht mehr geläufig
sind, dieses get8() legt ja das gelesene Byte in 3. Byte des Integers
ab.
@A.K. ...Hmm.. Motorola? Jedenfalls sind die der Meinung diesen Monitor
geschrieben zu haben...
1
MONITOR
2
3
4
Rev 1.1
5
Release Date
6
September 28,1989
7
8
9
10
******** DISCLAIMER ********
11
12
The FBUG monitor is the sole property of Motorola Inc. This software may be
13
distributed in whole or in part as public domain software. This software is
14
provided as is and in no event shall Motorola, Inc. be liable for any direct,
15
special, incidental, or consequential damages arising out of or connected with
16
a users poseesion or use of this software package, even if Motorola has advance
17
notice of the possibility of such damages.
18
19
Comments, questions or suggestions may be directed, in writing only, to:
20
21
Microprocessor Products Applications
22
6501 William Cannon Drive West 0E33
23
Austin, Texas 78735-8598
Gerade rief Einer an der fragte ob ich mal nach seiner Waschmaschine
gucken könnte. Der Monteur der vorher reingeguckt hat diagnostizierte
ein defektes "Steuerteil" für 270 Euro und die Maschine wäre Scheiße..
Ich komme mir nach Deiner Diagnose auch so vor wie der
Waschmaschinenbesitzer.
BTW: das ist ne Bauknecht..
@marcus: ich werde das probieren.
>Speziell für die etwas schräge Anbindung von 16 bit Peripherie an den>32-Bit Bus hat der 68k den movep-Befehl. Der wird aber erst interessant,>wenn Du mehrere Register auf einmal holen willst.
..ich kann mich erinnern das bei diesem movep Befehl irgendwas mit
geraden und ungeraden Adressen war, ich habe gelesen das die Peripherie
auf gerade Adressen gelegt werden sollte damit man diesen Befehl
benutzen kann. Was ist denn da dran? Die KatCe Hardware habe ich ja
nicht erfunden...
Gruß,
Holm
Der originale Code erinnert zwar tatsächlich mehr an einen Rübenacker
als an m68k-Assembler, es ist aber durchaus möglich, daß er bloß
deswegen nicht tut (schließlich tat er das ja schon mal, oder?), weil
man früher Compiler nicht mit taktisch klug eingestreuten volatile's vom
Optimieren abhalten mußte...
Vielleicht guckst Du dir das mal unter dem Aspekt nochmal an.
Markus F. schrieb:> Speziell für die etwas schräge Anbindung von 16 bit Peripherie an den> 32-Bit Bus hat der 68k den movep-Befehl.
Das ist hier nicht relevant, denn hier wird ein 68010 verwendet, der
sowieso nur einen 16-Bit-Datenbus hat.
Markus F. schrieb:> 32-Bit Bus hat der 68k den movep-Befehl. Der wird aber erst interessant,> wenn Du mehrere Register auf einmal holen willst.
Diese sehr exotische Befehl war für den Fall gedacht, in dem sich ein
16/32 Bit breites Peripherieregister auf 2/4 Bytes eines 8-Bit Busses
verteilt. Mit der späteren dynamischen Busbreite löste sich das Problem
in Luft auf.
Rufus Τ. Firefly schrieb:> Das ist hier nicht relevant, denn hier wird ein 68010 verwendet, der> sowieso nur einen 16-Bit-Datenbus hat.
Andersrum. Ab 68020 war er überflüssig.
Holm Tiffe schrieb:> @A.K. ...Hmm.. Motorola? Jedenfalls sind die der Meinung diesen Monitor> geschrieben zu haben...
Dem Code nach zu schliessen erledigen solche Jobs heute oft
Praktikanten.
Rufus Τ. Firefly schrieb:> Markus F. schrieb:>> Speziell für die etwas schräge Anbindung von 16 bit Peripherie an den>> 32-Bit Bus hat der 68k den movep-Befehl.>> Das ist hier nicht relevant, denn hier wird ein 68010 verwendet, der> sowieso nur einen 16-Bit-Datenbus hat.
Das ist zwar richtig, aber trotzdem falsch ;).
Es geht beim movep-Befehl natürlich um die Anbindung von 8-Bit
Peripherie an einen 16-Bit Datenbus (hab' ich oben schon falsch
eingeläutet).
Das tut wie es aussieht, 25° sind lt. Digitalthermometer gerade
plausibel :-)
>Der originale Code erinnert zwar tatsächlich mehr an einen Rübenacker>als an m68k-Assembler, es ist aber durchaus möglich, daß er bloß>deswegen nicht tut (schließlich tat er das ja schon mal, oder?), weil>man früher Compiler nicht mit taktisch klug eingestreuten volatile's vom>Optimieren abhalten mußte...>Vielleicht guckst Du dir das mal unter dem Aspekt nochmal an.
Naja .. hmm ... wie ich schon schrieb, der Code ist mir momentan nicht
gerade eingängig.
Allerdings hat das file unterschiedliche Defines für die verschiedenen
Prozessortypen.A Ich denke aber auch das das Ding alles andere als
fertig
war, ich weiß noch, das ich die Stackframe Geschichte für den 68010
anpassen mußte, Nach einem Trap hat der Debugger den 68010 als 68000
behandelt was schief gehen muß. Das ist aber irgendwann Mitte der 90er
gewesen als ich das das letzte Mal angefaßt hatte...
Der FBUG gefiel mir von verschiedenen Monitoren/Debuggern die für 68k
damals zur Verfügung standen am besten und als Ossi haben mir diese CPUs
besser gefallen als das Zeug was mir bis dahin über den Weg gelaufen
war,
allerdings sind die doch ganz schön komplex. Heute ist das Zeug so
veraltet das es keinen mehr interessiert. Bei mir ist das auch nur ein
nostalgischer Anfall und ich stehe noch lange nicht so in der Materie
das ich da nennenswert verbessern könnte, was wiederum der Grund ist,
warum ich mir einen Cross-GCC gebastelt habe.
BTW: Der gcc braucht da irgendwo auch noch Arbeit. Trotz der Tatsache
das ich den mit --with-cpu=m68000 konfiguriert hatte steht in seiner
libgcc rotzfrech 68020 code drin wenn man nicht explizit den Pfad
-L/home/holm/cross/m68k/lib/gcc/m68k-elf/4.6.2/m68000 angibt,
normalerweise sollte der dann der default sein.
Gruß,
Holm
Holm Tiffe schrieb:> ..ich kann mich erinnern das bei diesem movep Befehl irgendwas mit> geraden und ungeraden Adressen war, ich habe gelesen das die Peripherie> auf gerade Adressen gelegt werden sollte damit man diesen Befehl> benutzen kann. Was ist denn da dran? Die KatCe Hardware habe ich ja> nicht erfunden...
Das muß so.
mit movep kannst Du vier Registerinhalte in einem Langwort und in einem
Rutsch auf einmal übertragen, die geraden Adressen werden dabei
übersprungen.
Aha. Interessant, ich gucke mir das an.
>es ist aber durchaus möglich, daß er bloß>deswegen nicht tut (schließlich tat er das ja schon mal, oder?), weil>man früher Compiler nicht mit taktisch klug eingestreuten volatile's vom>Optimieren abhalten mußte...
..nicht tut ist falsch. Das geht schon, aber es vergehen Äonen ehe ich
zu der Information komme ob nun das Bit gesetzt ist oder nicht, die Zeit
habe ich da gerade nicht. Den DHT11 habe ich da auch gestern erst
angespaxt, der war vorher noch nie dran. Ich spiele doch nur mit der
Platine.
@A.K.:
>Dem Code nach zu schliessen erledigen solche Jobs heute oft>Praktikanten.
Ich war mir nun echt nicht mehr sicher, habe aber das alte Original file
noch mal ausgewickelt:
1
asmput8: mov.b asmdata+3,([asmaddr])
2
rts
3
4
asmput16: mov.w asmdata+2,([asmaddr])
5
rts
6
7
asmput32: mov.l asmdata,([asmaddr])
8
rts
9
10
asmget8: clr.l asmdata
11
mov.b ([asmaddr]),asmdata+3
12
bpl.b nosi8
13
or.l &0xffffff00,asmdata
14
nosi8: rts
15
16
asmget16: clr.l asmdata
17
mov.w ([asmaddr]),asmdata+2
18
bpl.b nosi16
19
or.l &0xffff0000,asmdata
20
nosi16: rts
21
22
asmget32: mov.l ([asmaddr]),asmdata
23
rts
24
25
putmpu:
26
mov.l ([RUSP]),%d0
das sieht so ziemlich genauso aus. Ich wars also nicht.
Ich nehme gerne Vorschläge zur Verbesserung entgegen, vielleicht braucht
das ja Jemand Anders nochmal. Ich schmeiße das Ergebnis gerne auf meine
Webseite.
Du solltest auch ein Bisschen nachsichtig sein, "heute" ist arg relativ
wenn man sich das Datum in der Quelle anguckt: 28.9.1989!
Gruß,
Holm
Holm Tiffe schrieb:> das sieht so ziemlich genauso aus. Ich wars also nicht.
Hatte auch nicht angenommen. Der Asm-Code ist freilich fubar, da lohnt
es sich nicht, irgendwas zu verbessern, solange man nicht auf Register
für Parameter umstellt. Also statt dem ASM Kram gleich in C:
1
intget8(intaddr)/* returns 8 bits not sign-extended */
2
{
3
return*(volatileuint8_t*)addr;
4
}
wenn der Compiler schon ANSI C frisst. ;-)
Oder noch einfacher
und im Code ohne Aufruf direkt PIT_PSRR verwenden.
> Du solltest auch ein Bisschen nachsichtig sein, "heute" ist arg relativ> wenn man sich das Datum in der Quelle anguckt: 28.9.1989!
Dachte ich mir, bei K&C C. Aber vielleicht gab es damals auch schon
Praktikanten.
Mein Kommentar war etwas verunglückt. Ich meinte damit, das Beispielcode
aus heutiger Zeit, wie in der STM32 Library, teilweise genauso
verbrochen aussieht.
Bei den PIT Adressen funktioniert das, beim LCD aber nicht.
Da ist ein 44780 Teil an 0xc04000 (ctrl) und 0xc04002 (daten)
dran, diesmal interessanterweise gerade Adressen.
Muß ich die Dinger als 16 Bit deklarieren?
Sorry, ist mir jetzt schon zu spät zum denken... ich knalle mich jetzt
vor die Glotze und penne sicher ein...
Gruß,
Holm
Holm Tiffe schrieb:> Bei den PIT Adressen funktioniert das, beim LCD aber nicht.
Weshalb nicht?
> Da ist ein 44780 Teil an 0xc04000 (ctrl) und 0xc04002 (daten)> dran, diesmal interessanterweise gerade Adressen.> Muß ich die Dinger als 16 Bit deklarieren?
Nein, grad so wie oben. Nur eben mit den anderen Adressen.