Hallo, ich habe ein Problem und weiß nicht genau wie ich es lösen
könnte. Da ich die ganze µC Sache eigentlich nur Hobbymäßig macht fehlt
mir auch einfach das Wissen dazu.
Also, Ich habe ein Wigglerkabel das an dem Parallelport einer Windows
Maschine hängt. Dazu eine Software in C die über den Port und das Kabel
per JTAG Lese und Schreibaktionen auf einem SMP8634 Prozessor ausführt.
Nun möchte ich den Rechner durch einen AVR ersetzen. Die Software habe
ich bereits auf einem Butterfly einigermaßen zum Laufen bekommen. Aber
was mir fehlt ist der Output.
Kann ich die parallele Schnittstelle irgendwie in dem AVR darstellen?
Das Wigglerkabel soll also an den AVR und der soll dann die
entsprechenden Befehle senden.
In dem WinProgramm habe ich folgendes gefunden.
TDI, TDO, TMS, TCK sind ja die Pins des JTAGs
Könnte ich einfach Pins im AVR dafür definieren?
Ich wäre euch echt sehr dankbar wenn ihr mir ein bisschen helfen
könntet.
Ich habe das Projekt angehängt, fall jemand einen Blick drauf werfen
möchte...
mfg
Jabberwock
@ Jabberwock (Gast)
>TDI, TDO, TMS, TCK sind ja die Pins des JTAGs>Könnte ich einfach Pins im AVR dafür definieren?
Sicher, such dir die schönsten aus ;-)
MfG
Falk
Hallo, danke für die sehr schnelle Antwort.
Also könnte ich einfach
statt
data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 <<
WTRST_N)
PORTB |= ( 1 << WTD0 ) | (0 << WTCK ) | (tms << WTMS ) | (tdi << WTDI) |
(1 << WTRST_N);
schreiben?
Wie ist das mit der Datenrichtung, das muss ja auch empfangen könne?
Weil ja auch Sachen gelesen werden.
@ Jabberwock (Gast)
>Wie ist das mit der Datenrichtung, das muss ja auch empfangen könne?>Weil ja auch Sachen gelesen werden.
Irgenwie glaube iuch nicht dass
"Die Software habe ich bereits auf einem Butterfly einigermaßen zum
Laufen bekommen."
Das sind elementare Grundlagen. Ohe die wird das GAR NICHTS.
AVR-GCC-Tutorial
MFG
Falk
Natürlich musst du die Ein/Ausgänge entsprechend konfigurieren. Wie das
geht steht im Handbuch deines uC. Am PC wird der Parallelport für solche
Basteleien gerne verwendet, da man ihn recht einfach ansteuern kann
und die Schnittstelle TTL Pegel hat. Mit einem Parallelen Bus hat das
nicht
mehr viel zu tun.
Sie lässt sich kompilieren und ich habe sie auf dem Butterfly.
Die Ausgaben des Porgrammes habe ich geändert und gebe die jetzt über
rs232 auf den Terminal aus. Das läuft soweit schon. Nur bleibt er hängen
weil er noch nichts lesen oder schreiben kann und dann auf Daten
wartet. Außerdem bekomme ich noch ein paar Warnungen aber es scheint zu
gehen.
Das Programm habe ich ja auch nicht geschrieben sondern nur angepasst
für den AVR.
Mir ist das nur mit der Ausgabe nicht ganz klar.
Wenn ich die Pins z.B als Ausgang definiere, wie kann er dann was
empfanen? Oder sind manche von den JTAG pins zum senden und andere zum
empfangen?
mfg
Jabberwock
@ Jabberwock (Gast)
>Wenn ich die Pins z.B als Ausgang definiere, wie kann er dann was>empfanen?
Kann er nicht.
> Oder sind manche von den JTAG pins zum senden und andere zum>empfangen?
Auf JTAG hast du von deinem Anwenderprogramm keinen Zugriff. Du musst
sogar das JTAG ver AVR Fuses bzw. Software abschalten, wenn du die
Pins in deinem Programm nutzen willst.
MFG
Falk
Das verstehe ich jetzt nicht, das Programm das am PC läuft macht das
doch auch. Es geht über den Parallelport auf die JTAG Schnittstelle
einer IPTV Box und das funktioniert bestens. Das gleiche soll der Atmel
auch machen.
Gut, JTAG kann ich abschalten. Brauch ich ja im Grunde nicht da das ja
alles die Software übernimmt.
Ich habe mal ein .txt angehängt mit einem Auszug aus dem Quellcode. Mir
wird nicht ganz klar wie die Daten übertragen werden.
Vieleicht verstehe ich da ja auch was total falsch.
Wäre super wenn du vieleicht einen Blick drauf werfen könntest.
mfg
Jabberwock
Guten Morgen, auch auf die Gefahr hin dass ich nerve...
Bei Wikipedia steht:
http://de.wikipedia.org/wiki/Joint_Test_Action_Group
Test Data Input (TDI) (positive Flanke)
Test Data Output (TDO) (negative Flanke)
Test Clock (TCK) (positive Flanke)
Test Mode Select Input (TMS)
Test Reset (TRST) (optional)
Also lege ich für die Pins TDI, TCD, TMS, TRST die Datenrichtung Ausgang
fest und TDO als Eingang.
Oder ist das jetzt totaler quatsch?
Muss ich vielleicht dazusagen das es sich um EJTAG handelt?
mfg
Jabberwock
Falk Brunner wrote:
>> Auf JTAG hast du von deinem Anwenderprogramm keinen Zugriff. Du musst> sogar das JTAG ver AVR Fuses bzw. Software abschalten, wenn du die> Pins in deinem Programm nutzen willst.>> MFG> Falk
Soweit ich den Jabberwock verstehe, will er doch nicht JTAG auf dem AVR
verwenden, sondern den AVR quasi als PC-Ersatz einsetzen und damit einen
ganz anderen Prozessor (SMP8634) über dessen JTAG-Schnittstelle
ansteuern. Oder nicht, Jaberwock? Dazu braucht er sich nicht um die
JTAG-Fuses am AVR zu kümmern.
Jabberwock wrote:
>Also lege ich für die Pins TDI, TCK, TMS, TRST die Datenrichtung Ausgang>fest und TDO als Eingang.>Oder ist das jetzt totaler quatsch?
Ich meine, das ist genau richtig.
Günter
@ Jabberwock
Das siehst du richtig.
Mit der Parallelschnittstelle am PC hat das nur soweit was zu tun, als
dass das die physikalische Schnittstelle ist. Ein paar Pins dieser
Schnittstelle werden zum Bitklappern benutzt.
Deine Idee ist interessant, stattdessen einfach ein paar Pins eines AVRs
zu nehmen. Ich habe immer noch im Hinterkopf, mein ungenutztes
Arthernet-Board für solche Zwecke zu missbrauchen ;-)
Ich würde solche Stellen komplett in Ruhe lassen:
data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 <<
WTRST_N)
und mir stattdessen ein paar Lowlevel-Funktionen basteln, die sich dem
Programm gegenüber wie ein PC-System präsentieren.
Auf die Art brauchst du keine verstreuten Änderungen im Quellcode,
sondern nur zentral 3-4 Funktionen, von denen die meisten einfache
Dummies sind.
Ob es schlauer ist, die WINDOWS_VERSION zu erweitern oder die nicht
WINDOWS_VERSION, muss man prüfen. Wenn man die WINDOWS_VERSION nimmt,
könnte es so aussehen:
// Ausgabe eines Wertes
// WINDOWS_VERSION
// _outp(0x378, data);
void _outp(uint16_t lptport, uint8_t data)
{
// hier data an die AVR Pins ausgeben...
}
// Eingabe eines Wertes
// WINDOWS_VERSION
// data = (unsigned char)_inp(0x379);
uint8_t _inp(uint16_t lptport)
{
uint8_t data;
// hier data von den AVR Pins einlesen...
return data;
}
// Dummies
#define CreateFile(A, B, C, D, E, F, G) (A)
#define CloseHandle(h)
,,,
Was man sich dann noch ansehen muss ist das Timing und der
Speicherbedarf. Die PC systeme könnten da für AVR Verhältnisse riesige
Puffer benutzen.
Ehrlich gesagt sehe ich beim Speicher eine viel grössere Hürde als bei
dem Klappern mit den Pins. Wenn ich das sehe:
int main(int argc, char** argv)
{
char choice[128];
...
if (argc > 1)
{
j = 1;
while (j < argc)
{
strcpy(choice,argv[j]);
if (strcasecmp(choice,"/wiggler")==0)
{
printf("\nusing Wiggler interface\n");
wiggler = 1;
...
kräuseln sich aus AVR Sicht mit kostbarem paar KB kleinem RAM die
Fussnägel, wenn 128 Bytes mal eben so verbraten werden. Sicher gibt es
noch mehr ähnliche Stellen.
Aber du schreibst, das ist bis auf die Pingeschichte schon lauffähig
portiert?
Ja genau so habe ich das gemeint.
Ich verstehe nur diese Funktion nicht. Die wird von allen Lese
/Scheibfunktionen aufgerufen. Ich denke das da die Bits an den Port
gegeben werden. Weil _outp(0x378, data); müsste das glaube ich machen.
#ifdef WINDOWS_VERSION // ---- Compiler Specific Code ----
19
_outp(0x378,data);
20
#else
21
//ioctl(pfd, PPWDATA, &data); Was ist das???
22
#endif
23
24
#ifdef WINDOWS_VERSION // ---- Compiler Specific Code ----
25
data=(unsignedchar)_inp(0x379);
26
#else
27
// ioctl(pfd, PPRSTATUS, &data);
28
#endif
29
30
data^=0x80;
31
data>>=(wiggler?WTDO:TDO);
32
data&=1;
33
34
returndata;
35
}
Was passiert denn da mit Data? und was bedeutet data >>=(wiggler ? WTDO
: TDO)
Wenn das die Ausgabefunktion ist, an welcher stelle bringe ich dann
meine Pins unter damit das nicht mehr über den Parallelport sonder über
die Pins des Atemls raus geht?
1
voidtest_reset(void)
2
{
3
clockin(1,0);// Run through a handful of clock cycles with TMS high to make sure
4
clockin(1,0);// we are in the TEST-LOGIC-RESET state.
Oh, du hast meine Frage ja schon beantwortet...
Danke für die schnelle Antwort, so hatte ich mir das auch gedacht nur
war ich mir nicht sicher ob es überhaut gehen würde.
Du hast das jetzt aus dem .txt genommen, oder? das ist der originale PC
Code. Ganz oben in dem ersten Post ist der angepasste Code in dem .zip
(AVRStudio Projekt) Da ist einiges rausgeflogen.
mfg
Jabberwock
Jabberwock wrote:
> Ja genau so habe ich das gemeint.>> Ich verstehe nur diese Funktion nicht. Die wird von allen Lese> /Scheibfunktionen aufgerufen. Ich denke das da die Bits an den Port> gegeben werden. Weil _outp(0x378, data); müsste das glaube ich machen.
Auf einem Windows System, ja.
Auf einem Unix System macht das ioctl (Damit hat sich deine
im Code eingebaute Frage: Was ist das??? erledigt)
>> Was passiert denn da mit Data? und was bedeutet data >>=(wiggler ? WTDO> : TDO)
Das ist eine ganz normale Kombination aus einem Schiebeoperator >>=
und einer ?: Operation
Die Operation ?: macht im Grunde folgendes
a = Vergleich ? Ja_Ausdruck : Nein_Ausdruck
und ist fast äquivalent zu
if( Vergleich )
a = Ja_Ausdruck
else
a = Nein_Ausdruck
Der einzige Unterschied ist, dass ?: ein Ausdruck ist, der
ein Ergebnis liefert. Trifft die Bedingung zu, dann ist das
Ergebnis des kompletten Ausdrucks der Ja_Ausdruck, trifft er
nicht zu, dann eben den Nein_Ausdruck
wiggler ? WTDO : TDO
liefert als Ergennis also entweder WTDO oder TDO, je nachdem
welchen Wert (nicht 0 oder 0) die Variable wiggler hat.
Und der Rest:
1
a>>=b;
ist identisch zu
1
a=a>>b;
a wird um b Stellen nach rechts geschoben.
1
data>>=(wiggler?WTDO>:TDO);
Hier wird also data um entweder WTDO oder TDO Stellen nach rechts
verschoben, abhängig davon, ob wiggler 0 oder nicht 0 ist.
Die 'Langform' dafür lautet
> Wenn das die Ausgabefunktion ist, an welcher stelle bringe ich dann> meine Pins unter damit das nicht mehr über den Parallelport sonder über> die Pins des Atemls raus geht?
Genau in dieser Funktion machst du die Ausgabe.
Anstelle von
_outp(0x378, data);
kommt
PORTB = data;
Ob dann allerdings die Pinbelegungen um Port zu denen des
parallel Ports passen, musst du hardwaremässig sicherstellen.
Karl heinz Buchegger wrote:
> Ob dann allerdings die Pinbelegungen um Port zu denen des> parallel Ports passen, musst du hardwaremässig sicherstellen.
... geht auch in Software, indem die Makros für die JTAG-Pins für den
AVR anders definiert werden als für den Parallelport, also z.B. sowas:
1
#define WTD0 PINB0
2
#define WTCK PINB1
3
// etc.
Das hat den Vorteil, daß man bei der Zuordnung der JTAG-Signale zu den
Portpins freie Hand hat.
Jabberwock wrote:
> ja genau... so langsarm verstehe ich es, vielen Dank.>> Also definiere ich Pins und bei else schicke ich data auf den Port.>> ca. so...>>
1
>#ifdefWINDOWS_VERSION// ---- Compiler Specific Code ----
2
>_outp(0x378,data);
3
>#else
4
>
5
>// PB0 = WTDO PB1 = WTCK PB2 = WTMS PB3 = WTDI
6
>PB4=WTRST_N
7
>PORTB|=(1<<PB0)|(0<<PB1)|(tms<<PB2)|(tdi<<PB3)|
8
>(1<<PB4);
9
>#endif
10
>
11
>
Äh, nein.
Mittels | (also: Oder) kannst du nur Bits auf 1 setzen
aber nicht einzelne Bits auf 0.
Bau dir zuerst, so wie im Originalcode, das komplette Byte
in einer Variablen zusammen und gib es dann in einem Rutsch
PORTB = data;
aus.
Ja ist mir auch schon aufgefallen... da war ich zu übereifrig.
habe es jetzt so.
[c]
#define WTD0 PINB0
#define WTCK PINB1
#define WTMS PINB2
#define WTDI PINB3
#define WTRST_N PINB4
DDRB = 0xff;
DDRB &= ~(1<<PB0);
#ifdef WINDOWS_VERSION // ---- Compiler Specific Code ----
_outp(0x378, data);
#else
//original
//ioctl(pfd, PPWDATA, &data);
// Ausgabe auf die Pins
PORTB =(PPWDATA, &data);
#endif
[c/]
Muss ich noch irgendwas beachten was der Parallelport sonst übernimmt
was mir hier dann noch fehlen würde?
Hm... jetzt habe ich ein neues Problem...
Weiß jemand was das PPISDATA und PPIGSTATUS macht?
1
#else
2
//original
3
//ioctl(pfd, PPWDATA, &data);
4
5
// Ausgabe auf die Pins
6
PORTB=(PPWDATA,&data);
im Headerfile wird es wie unten definiert. Da fehlen mir dann wohl die
includes.
Brauche ich die? Die sind ja für die Liunxvariante. Die Frage ist was
bewirkt das in der Ausgabe?
Jabberwock wrote:
> // Ausgabe auf die Pins> PORTB =(PPWDATA, &data);
Ich frag mich sowieso schon die ganze Zeit, was das sein soll.
Was ist an einem
PORTB = data;
so schwierig?
Ich weiß halt nicht was das bewirkt. Die Frage ist ja was der komische
CPU auf der anderen Seite haben will. Aber ich denke das ist nur config
für den Parallelport, oder?
Ich kann es leider nicht testen das ich die CPU dafür nicht hier habe.
Außerdem bekomme ich noch 7-mal die Warnung die immer auf die gleiche
Variable zeigt.
left shift count >= width of type
Was bedeutet das?
Jabberwock wrote:
> Ich weiß halt nicht was das bewirkt.
Meine ehrliche Meinung:
Mach ein paar Vorübungen, ala: Wie schalte ich eine am Port
angeschlossene Led ein und wieder aus.
Das sind absoluet Grundlagen!
Einfach an den Port zuweisen und schon erscheint das Bitmuster
an der Hardware. Mehr ist da nicht.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#I.2FO-Register>> left shift count >= width of type>> Was bedeutet das?
Bei welcher Zeile?
// Clear the access pending bit (let the processor eat!)
85
set_instr(INSTR_CONTROL);
86
ctrl_reg=ReadWriteData(PROBEN|SETDEV);
87
88
}
89
}
90
}
Die anderen Warunungen sind in anderen Funktionen aber die gleiche
Variable.
../x300tpatchv2.c:360: warning: left shift count >= width of type
../x300tpatchv2.c:361: warning: left shift count >= width of type
../x300tpatchv2.c:370: warning: left shift count >= width of type
../x300tpatchv2.c:842: warning: left shift count >= width of type
../x300tpatchv2.c:842: warning: left shift count >= width of type
../x300tpatchv2.c:854: warning: left shift count >= width of type
../x300tpatchv2.c:855: warning: left shift count >= width of type
../x300tpatchv2.c:291: warning: 'ejtag_read_h' defined but not used
avr-gcc.exe -mmcu=atmega169 x300tpatchv2.o -o Modchip.elf
avr-objcopy -O ihex -R .eeprom Modchip.elf Modchip.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load"
--change-section-lma .eeprom=0 --no-change-warnings -O ihex Modchip.elf
Modchip.eep || exit 0
c:\WinAVR-20070525\bin\avr-objcopy.exe: there are no sections to be
copied!
AVR Memory Usage
----------------
Device: atmega169
Program: 4068 bytes (24.8% Full)
(.text + .data + .bootloader)
Data: 1055 bytes (103.0% Full)
(.data + .bss + .noinit)
Build succeeded with 11 Warnings...
Michael Wilhelm wrote:
>>Data: 1055 bytes (103.0% Full)>>(.data + .bss + .noinit)>>>>Build succeeded with 11 Warnings...>> nicht mal eine Fehlermeldung. Nicht schlecht.>
:-)
Nur sind die Warnungen keineswegs harmlos.
@Jabberwock
> ../x300tpatchv2.c:360: warning: left shift count >= width of type
Und du glaubst jetzt wirklich ich zähle in deinem unvollständigen
Code die Zeilen aus bis ich bei 360 bin?
Aber was solls.
Was sagt den die Fehlermeldung
left shift count >= width of type
Da ist von einem left shift count die Rede. Wörtlich übersetzt:
Die Anzahl (der count) um die nach links geschoben (left shift)
wird.
Aha irgendwas stört den Compiler bei dem Versuch einen << anzuwenden.
Was kann das blos sein?
>=
dieser count ist also größer gleich.
Ja was den nun? Größer als was?
width of type
Die Breite (width) des Datentyps (type)
Zusammengefasst und in ein etwas besseres Deutsch verpackt:
Es wird versucht einen Datentyp so oft nach links zu verschieben,
daß alle Bits links herausfallen und nichts übrig bleibt.
Beispiel:
Wenn ich einen uint8_t 9-mal nach links verschiebe, dann ist von
den originalen Bits kein einziges mehr im uint8_t enthalten.
Man könnte auch sagen:
uint8_t i;
i << 9;
ist eine komplizierte Schreibweise für
0
War doch nicht so schwer, oder? Nichts was sich nicht mit ein
bischen Nachdenken erklären lässt.
>Und du glaubst jetzt wirklich ich zähle in deinem unvollständigen>Code die Zeilen aus bis ich bei 360 bin?
Natürlich nicht, deshalb sind da Kommentare in dem Code der die Stellen
der Warnungen anzeigt...
Der Vollständige Code ist dem ersten Post angehängt...
Wobei da noch ein paar mehr Warnungen drin sind die ich aber
größtenteils weg bekommen habe.