Hallo zusammen, gibt's hier noch mehr Fans vom Schneider (Amstrad) CPC 464? Als Fan der Hardware-Sprachsynthese habe ich einmal einen Emic 2 Sprachsynthesizer für den CPC aufgebaut. Warum poste ich das hier? ATMega 328p wird für parallel-nach-seriell Wandlung verwendet, und als Buffer / Driver. Dazu habe ich auch eine Frage (s.u.). Doch zunächst einen zum YouTube Video, damit klar ist, um was es geht: https://youtu.be/C5BnD1NPwGw Das ist die Prototype-Breadboard-Version. Ich habe auch schon eine Platine in der Produktion (erstellt mit KiCad + OSHPark). Mehr demnächst. Meine Frage: die ursprüngliche Idee war, direkt mit dem 328 am Datenbus zu lauschen, und direkt Bytes vom Datenbus des CPCs zu lesen und zu puffern. Die Addressdekodierung mache ich mit 2 PALs (Lattice / Atmel G18V8), die ein "Adresses erkannt"-Signal erzeugen sobald die IO-Addresse &F9E0 auf dem Addressbus erscheint. Ursprünglich sollte dieses Signal dann im 328 einen Interrupt mittels INT0 auslösen, der sich dann schnell das Datenbyte vom Bus holen und merken sollte. Da Timing natürlich alles ist, habe ich den 328 sogar mit 16 Mhz getaktet (der CPC ist mit 4 MHz unterwegs). Soweit der Plan. Hat aber nicht geklapp - wohl aus mehreren Gründen: Zum einen dauert die Interrupt-Behandlung wohl einfach zu lange im 328, und das Byte ist "schon weg vom Datenbus" wenn der 328 es denn lesen will. So benötigte ich dann sogar ein 74LS343 Flip Flop, um das Byte vom Datenbus "zu latchen", damit es dann für den 328 zum Auslesen längere Zeit anliegt. So weit, so gut. Zum anderen, und das ist das größere Mysterium, scheint es nicht so einfach zu sein, zuverlässig mit den IO-Ports des 328 ein ganzes Byte parallel zu lesen, zumindest nicht schnell. Als Lösung musste ich auf einen Protokoll-Trick zurückgreifen: um Bytes "AB" (65 66 ASCII) an den 328 zu senden, alterniere ich die Nutzbytes (65 66= mit 0-Bytes, und setze das 8. Bit in den Nutzbytes (Sprachsynthesizer verwendet nur ASCII 7 Bit)... also sende ich 193 (= 65+128) 0 194 (= 66 + 128) 0 statt 65 66, und der 328 kann dann die 0-Bytes und das 8. Bit zur "Taktung / Synchronisation" verwende. Das wird einfach in einem Array gepuffert. Mit etwas Wartezeit für das 0-Byte zwischendrin kann der 328 dann die Bytes vom CPC-Datebus (bzw. dem Flop Flop) sehr zuverlässig lesen und puffern, und dann, wenn "Enter" kommt, per seriell an den Emic 2 senden. Wenn ich diesen Trick nicht anwende, bekomme ich beim Auslesen der Bytes mit dem 328 komische Effekt, z.B. Bitflips (Bits die 0 sein sollten, sind noch 1 wenn sie es vorher waren), und andere komische Effekte. Anscheinend scheint eine 0 zwischen 2 Nutzbytes erforderlich zu sein, damit die Input des 328 "wieder runter kommen". Und das scheint eine Zeit zu dauern? Hmm. Meine Frage wäre - kommt jemanden dieses Problem bekannt vor, und/oder hat eine Idee, wie es zu lösen ist? Ich meine, die Lösung oben funktioniert, aber es wäre doch schöner, wenn ich einfach 65 66 + "Addresse erkannt"-Signal an INT0 per Interrupt senden könnte. Das einzige, was für mich momentan funktioniertt, ist eine "tight loop" und polling der Art "loop-until-set(bit8)" und so weiter. Ich weiß, man kann den Z80 im CPC auch "drosseln" mit Waitstates, aber das wollte ich nicht. Wenn ich schon einen uP als intelligenten Treiber (Buffer + Seriellen Konverter) verwende. UART Chip will ich auch nicht. Bustreibe macht keinen Unterschied denke ich - das FlopFlop (373) oben ist gut genug. Gruß, Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Wenn ich das richtig verstehe, geht es um einen parallel zu seriell Wandler der mit &F9E0 Adressiert wird und sofort nach Erhalt wandelt. Passt das Ganze nicht auch in ein CPLD? Das dürfte schnell genug sein.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Danke für den Tipp - klingt gut! Allerdings habe ich keinerlei Erfahrung mit CPLDs... außerdem ist Timing kritisch - der Emic 2 benötigt 8N1 seriell mit 9600 Bauds. Ich habe ein paar FPGA-Experimentierboards, das wäre natürlich auch noch mal einen Versuch wert. Mit dem 328 und SUART.h ist das serielle Interface zum Emic 2 ein No-Brainer - ich war immer der Meinung, dass der 328 doch irgendwie schnell genug sein müsste, um ein paar Bytes, die mit ein paar KHz Frequenz kommen, zuverlässig zu puffern - vielleicht habe ich ihn ja überschätzt :-) Oder ich muss mal die nächst größere Version vom AVR probieren.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Ich habe ein paar FPGA-Experimentierboards Und auch schon etwas damit gemacht, oder? Da es nur um Register, Adressvergleicher und evtl. Baudteiler geht, dürfte der Unterschied zum CPLD Design nur minimal sein.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
pegel schrieb: > Michael W. schrieb: >> Ich habe ein paar FPGA-Experimentierboards > > Und auch schon etwas damit gemacht, oder? Nein, ich bin Anfänger... habe 2 Bücher über FPGA-Programmierung gelesen, aber noch nichts praktisches gemacht. Ich habe einen DEO-Nano, einen Elbert 2, und einen Papilio DUO. Es erschien mir etwas "Overkill", die guten Teile für soetwas "profanes" einzusetzen - aber sicherlich ein gutes Lernprojekt für mich!
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Was wäre denn ein geeignetes CPLD für meine Zwecke?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Mein Favorit für kleine Sachen ist die XC9500 Serie. Ohne XL dahinter da die für 5V Logik sind. Bei deinen FPGA Boards würden die Pegelwandler vermutlich den größten Teil der Schaltung ausmachen, oder?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
pegel schrieb: > Bei deinen FPGA Boards würden die Pegelwandler vermutlich den größten > Teil der Schaltung ausmachen, oder? Gut möglich - in meiner Ignoranz / Unwissenheit hatte ich ehrlich gesagt gehofft, dass ich keine brauchen würde :-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Welche Software hast du für dein Elbert 2? Wird der XC95 unterstützt? Kann der Onboard Programmer auch externes JTAG?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Das sieht interessant aus, ich schalt mal das Abo on :) Btw sehr geiles Projekt und die Sing-Funktion ist der Hammer^^ Ansonsten ... Es gibt 5V nach 3,3V Transceiver (bidirktional) 74LVX4245 ... Die sind recht klein und verhalten sich wie normale 245er und haben das nette Feature, dass eine Seite mit 5V und die andere Seite mit 3,3V bestromt wird. http://www.st.com/content/ccc/resource/technical/document/datasheet/6e/85/52/2a/cb/3d/4c/47/CD00001693.pdf/files/CD00001693.pdf/jcr:content/translations/en.CD00001693.pdf Jetzt noch 5V CPLDs zu verwenden wäre zwar schön vintage, aber die sind mittlerweile schwer erhältlich ... Lieber dann gleich XC9572XL oder sowas verwenden und 1-2 Transceiver vorne dran bauen. Die sind an den Eingängen 5V-Tolerant, aber für eine Rückantwort an die Z80-CPU könnte man dann die Transceiver verwenden.
:
Bearbeitet durch User
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Gute Ideen, dank Euch! Am Liebsten wäre mir ja ein "parallel-nach-8N1-seriell-ich-mach-alles-für-Dich" Chip - vielleicht gucke ich mir ja doch noch mal an, wie ein "retro" 16C550 zu beschalten wäre. Ich habe immer davor zurückgeschreckt, weil ich dachte, die erfordern komplizierte Konfigurationseinstellungen. Aber schnell genug für diese Anwendung sollten die wohl sein, nicht wahr? (Schneller als der AVR 328).
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
http://www.cpcwiki.eu/index.php/File:Rs232cpc.lzh von der Seite: http://www.cpcwiki.eu/index.php/Z80_STI_RS232_interface den MK3801 gibt es hier: ebay 132019022498 Ist eigentlich alles drin inkl. Code.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Wie wärs mit einem FIFO zum zwischenspeichern ? z.B. 2x 74HC40105
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Für die kleine Logik vor dem MK3801 kannst du deine PAL weiter benutzen. Der Aufwand hält sich also sehr in Grenzen.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Jetzt nochmal einen Schritt zurück von zusätzlicher Hardware zu einer Softwarelösung. Was wäre, wenn Du den Port so auslesen würdest?
1 | .org INT0 |
2 | in r15,PINB ;1 clock cycle |
3 | rjmp handle_exint |
Was hat der 328 für eine Interrupt-Latency, 4 Takte? Dann hättest Du 5 Takte nach dem Interrupt den Wert im Register, bei 16 MHz also nach knapp über 300 ns (bei 20 MHz nur 250 ns, das sollte beim einem 4 MHz-Z80 WIMRE eigentlich schnell genug sein). Alles weitere ist dann nicht mehr so zeitkritisch und kann danach in Ruhe erledigt werden (inkl. Sichern des Statusregisters usw.). Voraussetzung wäre, daß R15 (oder irgendein anderes Register) exklusiv für den Interrupt reserviert wird und nirgendwo anders im Programmcode verwendet wird. Günstig wäre auch, wenn der Controller im Moment des Interrupts im Idle-Modus wäre, damit ist die Interrupt-Latency konstant. Falls erst ein Puffer im Controller gefüllt und dann der String zum Sprachsynthesizer gesendet wird, sollte das doch möglich sein.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
pegel schrieb: > Für die kleine Logik vor dem MK3801 kannst du deine PAL weiter benutzen. > Der Aufwand hält sich also sehr in Grenzen. In der Tat, den MK3801 kannte ich nicht, das sieht ja wirklich einfach aus!! Ich werde mir mal 2 davon bestellen! Super Tipp, Danke!
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Musst aber noch eine Einstellung für 9600 Baud hinzu fügen. Geht aber: http://schuetz.thtec.org/mccomputer/Mostek%20-%20MK3801%20Application%20Notes.pdf In der README.TXT steht zu Not auch die Kontaktadresse.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Verrätst du uns woher du den Emic 2 hast?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Horst M. schrieb: > Jetzt nochmal einen Schritt zurück von zusätzlicher Hardware zu einer > Softwarelösung. > > Was wäre, wenn Du den Port so auslesen würdest? > .org INT0 > in r15,PINB ;1 clock cycle > rjmp handle_exint > > Was hat der 328 für eine Interrupt-Latency, 4 Takte? > Dann hättest Du 5 Takte nach dem Interrupt den Wert im Register, bei 16 > MHz also nach knapp über 300 ns (bei 20 MHz nur 250 ns, das sollte beim > einem 4 MHz-Z80 WIMRE eigentlich schnell genug sein). Alles weitere ist > dann nicht mehr so zeitkritisch und kann danach in Ruhe erledigt werden > (inkl. Sichern des Statusregisters usw.). Hallo Horst, ich hatte C verwendet, und habe den Sourcecode jetzt gerade nicht vorliegen, aber das Programm mit INT0-Interrupt sah im Wesentlich so aus (aus dem Gedaechtnis, ist nur ne Skizze!): volatile uint8_t index = 0; ... buffer array etc. dann: ISR(INT0_vect) { unit8_t byte = (( PINB & 0x00011110) >> 1) | ( PINC & 0x00001111) << 4) buffer[index] = byte; index++; } void initInterrupt0(void) { EIMSK |= (1 << INT0); EICRA |= (1 << ISC00); sei(); } int main(void) { initInterrupt0(); while (1) { if (index > 0 && buffer[index-1]=10) { sendToEmic2(); index = 0; } } return 0; } Ich hatte keine 8bit "am Stueck" frei an den Ports, deswegen musste ich ein Nibble vom PORTB und eines vom PORTC lesen und verknusen. Evtl. kostet selbst das zu viel Zeit... evtl. sollte ich die Daten lieber "Raw" in 2 Arrays speichern (eines fur PORTB, eines fuer PORTC), und vor dem Abspielen / Senden an den Emic 2 konvertieren. Mag sein, dass das ein paar Takte Zeit spart. Interessant ist jedoch, dass selbst wenn ich die Bytes langsam sende, ich am Ende immer Murks mit dieser Loesung im buffer habe. Weshalb ich davon ausgehe, das die Eingaenge vom 328 irgendwie nicht geeignet sind fuer diese Aufgabe (parasitaere Kapazitaeten o.ae.?) Dabei hatte ich fuer die INT0-Konfiguration sowohl fallende als auch steigende Flanke und "Pin CHange" etc. auspropiert... am Ende hatte ich stets Murks im buffer. Mit oder ohne Flipflop. Evtl. genuegt das INT0-Signal, dass meine PLDs erzeugen, nicht den Qualitaetsanforderungen des 328... das 74LS343 hat allerdings keine Probleme mit dem Signal. Vielleicht ist es zu kurz oder was auch immer? Gepuffert und so weiter hatte ich also...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
PS Ich hatte auch beobachtet, dass der buffer gefuellt wird. Aber eben mit Murks - Bitflips etc. Wenn ich z.B. Bytes 0, 1, 2, 3, 4, ... sendete, konnte ich beobachten, dass Bits die vorher 1 waren und nun 0 sind, noch als 1 registriert wurden - im Array hatte ich dann oft sowas wie 0, 1, 3, 3, 7, ...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
... und die momentane "Loesung" fuer dieses Phaenomen ist fuer mich, immer ein 0-Byte zwischen 2 Nutzbytes zu senden. Damit klappt es dann... allerdings auch nur, wenn ich auf die INT0-Routine verzichte. Ich mache momentan also sowas wie while(1) { loop_until_bit_set(bit8_pinc); byte = (( PINB & 0x00011110) >> 1) | ( PINC & 0x00001111) << 4); buffer[index] = byte; index++; if (byte = 10) { sendToEmic2(); index = 0; } } Das ist die einzige Loesung, die fuer mich funktioniert. Mit 0-Bytes zwischendrin und Bit8-gesetzt-Protokoll, wie oben beschrieben.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
> Verrätst du uns woher du den Emic 2 hast?
Ich lebe in Palo Alto, CA, da gibt es den bei Fry's Electronic zu
kaufen. Ca. 55 $. Es gibt ihn aber auch bei Amazon.com (.de weiss ich
nicht).
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Bei Licht betrachtet ist der 328p mit seiner Portbelegung dafür wirklich nicht ideal, Quarz an Port B, USART an Port D und bei Port C fehlt ein Pin. Da ist kein kompletter Port mit 8 Bits übrig. Mit einem 40-Pinner ginge's einfacher, mit 20MHz könntest Du's am 328 evtl. nochmal so probieren:
1 | .org INT0addr |
2 | in r14,PINB |
3 | in r15,PINC |
4 | rjmp handle_exint |
Ist zwar nur ein Takt mehr, könnte aber evtl. knapp werden (der Z80 hat für den OUT-Befehl doch nur 3 Taktzyklen, oder? *). Das Ausmaskieren, Zusammenschieben usw. machst Du dann in der restlichen Interruptroutine. Wenn Du zwei Register aus dem Upper-Block ab R16 spendierst, gehen dann auch die Immediate-Befehle, spart noch ein paar Zyklen. * Hab's eben nochmal im Kieser/Meder gecheckt - IORQ ist 1 1/2 Prozessortakte Low, das sind bei 4 MHz also 375 ns, könnte also reichen.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Horst M. schrieb: > Was wäre, wenn Du den Port so auslesen würdest? > >
1 | > .org INT0 |
2 | > in r15,PINB ;1 clock cycle |
3 | > rjmp handle_exint |
4 | > |
Nur nebenbei: INT0 sollte wohl heißen: INT0addr... > Was hat der 328 für eine Interrupt-Latency, 4 Takte? Wie jeder AVR8 ohne externen Speicher und 128k oder weniger Flash. Leider ist das weniger als die halbe Wahrheit, denn das ist nur die konstante Interruptlatenz. Dazu kommt die variable, die oft viel größer ist. Selbst unter allergünstigstenen Umständen (keine cli/sei-Blocks im Code und keine konkurrierenden Interrupts, keine Unterprogramme in main und keine Datenzugriffe auf den Flash) hast du immer noch eine variable Latenz von einem Takt, die du zur konstanten hinzurechnen musst. Und wann hat man schonmal so extrem günstige Umstände... > Dann hättest Du 5 Takte nach dem Interrupt den Wert im Register Es sind bei günstigsten Umständen (s.o.) im worst case immer noch 6 Takte. > Günstig wäre auch, wenn der Controller im Moment des Interrupts im > Idle-Modus wäre, damit ist die Interrupt-Latency konstant. Günstig? Ich würde es eher eine notwendige (aber nicht hinreichende) Voraussetzung dafür nennen, dass deine Rechnung überhaupt jemals aufgeht... Dann dann (und nur dann) sind die meisten obigen Einschränkungen hinfällig. Bleiben beim Mega328 "nur" noch: konkurrierende Interrupts...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Habe es jetzt zu ähnlichen Preis hier gefunden: https://www.sparkfun.com/products/11711 Freundlicher Weise wie immer mit Schaltung und Code Beispiel.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
c-hater schrieb: >> Dann hättest Du 5 Takte nach dem Interrupt den Wert im Register > > Es sind bei günstigsten Umständen (s.o.) im worst case immer noch 6 > Takte. Ja, timing etc. ist wie gesagt nur ein Problem. Mit dem FlipFlop in der Schaltung liegt das Datenbyte ja solange an, wie ich es will, also kein Problem. Selbst wenn ich Bytes langsam mit dem CPC sende, und vom FlipFlop lese, hatte ich wie gesagt das Problem, dass eine Sequenz wie 0, 1, 2, 3, 4 als 0, 1, 3, 3, 7 im buffer erschien. Dabei hat das FlopFlop stets die richtigen Werte (kontrolliert). Da ist also was schraeg mit den Eingaengen des 328. Was ich noch mal probieren kann ist, nachdem ich den INT0 gekriegt habe, ein paar ms zu warten, bevor ich die beiden Nibbles lese, in der Hoffnung, dass die parasitaeren Kapazitaeten oder was auch immer verantwortlich ist fuer den Effekt, dass 0 BIts die vorher 1 waren noch als 1 erscheinen, damit kompensiert werden. Komisch ist das schon, muss ich sagen.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Na ja. Ich sehe im Aufbau recht lange Leitungen und auch nur ein Abblock C am Atmega. Die anderen IC, hmm.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Weiss jemand, mit welcher Baud-Rate man maximal von den Eingaengen lesen kann, zuverlaessig? Ich meine, um Zuverlaessig 0,1,0,1,... als alternierende Bitfolge and einem einzelnen PIN zu empfangen. (Senden scheint einfacher zu sein - ich weiss, da geht es bis in die MHz ohne Probleme, aber die Eingaenge im 328 scheinen ja eine Art eierlegende Wollmilchsau zu sein, mit ADC und was auch immer da vor sich geht...)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
> byte = (( PINB & 0x00011110) >> 1) | ( PINC & 0x00001111) << 4);
Das ist aber nicht das Originalprogramm, oder?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Da ist > also was schraeg mit den Eingaengen des 328. Nein, die funktionieren, darauf kannst du einen lassen.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: >> byte = (( PINB & 0x00011110) >> 1) | ( PINC & 0x00001111) << 4); > > Das ist aber nicht das Originalprogramm, oder? Nein, eine Skizze aus dem Gedaechtnis. Aber schon so ungefaehr - hast Du bessere Vorschlaege / Ideen, wie man 2 Nibbles von PINB, PINC in ein Byte verwandelt?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Es geht um 0x... <-> 0b...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Es geht um 0x... <-> 0b... Aehh, ja ist klar, danke ;-) Nein nein, das echte Programm verwendet schon 0b... ;-) C ist nicht meine Haupt-Sprache, daher spielt mir mein Gedaechtnis oefters mal einen Streich - if (byte = 10 ) ... sollte wohl auch eher if (byte == 10) ... heissen, ich weiss ;-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
c-hater schrieb: > Michael W. schrieb: > >> Da ist >> also was schraeg mit den Eingaengen des 328. > > Nein, die funktionieren, darauf kannst du einen lassen. Na ja, schon, aber irgendwie sind sie "traege"... kennt keiner das Phaenomen? Vielleicht liegt es ja wirklich an zu langen Leitungen. Aber 15 cm sind doch nicht lang... und die Frequenzen sind laecherlich gering (im kHz-Bereich!)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Aber die PAL und Logic IC arbeiten im ns Bereich, die sehen das vielleicht ganz anders.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Selbst wenn ich Bytes langsam mit dem > CPC sende, und vom FlipFlop lese, hatte ich wie gesagt das Problem, dass > eine Sequenz wie 0, 1, 2, 3, 4 als 0, 1, 3, 3, 7 im buffer erschien. > Dabei hat das FlopFlop stets die richtigen Werte (kontrolliert) Was ich also nicht verstehe, ist - wie kann es sein, dass ein Retro FLipFlop von 1968 das Datenbyte mit dem generierten Signal korrekt latchen kann, und der 328 kriegt das nicht hin.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Na ja, schon, aber irgendwie sind sie "traege"... kennt keiner das > Phaenomen? Naja, sie hängen bis zu einem Takt dem realen Geschehen hinterher. Das ist dokumentiert, ist der Synchronisierung mit dem MCU-Kern geschuldet. Alles darüber hinaus kommt entweder von außen oder von mieser Software... Dazu gehört natürlich auch Software, die dieser dokumentierten Verzögerung nicht Rechnung trägt...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Vielleicht ist auch nur dein Breadboard von ähnlicher Qualität wie meins. Habe auch schon ein paar mal an mir gezweifelt dadurch.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
AVR-Eingänge träge? Ich betreibe hier einen ATmega644P mit 25 MHz und lese mit 'in r0,PINA' ... 'in r29,PINA' 30 Bytes in 1.2 us ein.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Ich betreibe hier einen ATmega644P mit 25 MHz und > lese mit 'in r0,PINA' ... 'in r29,PINA' 30 Bytes in 1.2 us ein. OK, guter Datenpunkt! Das ist allerdings auch ein dickerer Hammer als der 328, stimmt's?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
pegel schrieb: > Vielleicht ist auch nur dein Breadboard von ähnlicher Qualität wie > meins. > Habe auch schon ein paar mal an mir gezweifelt dadurch. Ich habe ja ein PCB in Produktion,,, bin gespannt, ob es besser geht damit! Zumindest habe ich mein PCB so entworfen, dass das Signal auch an INT0 anliegt, damit kann ich das dann einfach ausprobieren. Ansonsten habe ich ja noch die andere Loesung.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
> Das ist allerdings auch ein dickerer Hammer als > der 328, stimmt's? Schon, ich habe ja nicht die Zeit, um ein Byte aus zwei Stücken zusammenzusetzen. Aber die Technologie ist die gleiche.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
c-hater schrieb: > Alles darüber hinaus kommt entweder von außen oder von mieser > Software... Verstehe. Na ja, in meinem Fall ist die Software so minimal, dass da eigentlich kaum was zu optimieren ist auf der C-Seite, oder? (Und wenn, wuerde ich hoffen, dass GCC das fuer mich macht ;-) )
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Schon, ich habe ja nicht die Zeit, um ein Byte aus zwei Stücken > zusammenzusetzen. ... das mache ich ja auch nur unfreiwilig, weil ich den Quarz habe und SIN / SOUT...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Dann splitte die Sache zum Test doch einfach mal. Jeweils nur die Bits von einem Port auslesen und sehen was wirklich ankommt.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Ich betreibe hier einen ATmega644P mit 25 MHz und > lese mit 'in r0,PINA' ... 'in r29,PINA' 30 Bytes in 1.2 us ein. Verwendest Du eine spezielle Beschaltung, um diese Raten zu erreichen? Bist Du sicher, dass keine Artefakte auftreten? Ich ware mir z.B. nicht sicher, ob ich AVCC and VREF und diese Sachen beschalten sollte, da ich ja eigentlich keine AD-Wandlung benoetigt. Evtl. hat das aber Einfluss auf "Pin-Traegheit" oder was auch immer? Oder alle nicht benutzten PINs auf GND ziehen, ...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Na ja, in meinem Fall ist die Software so minimal, dass da > eigentlich kaum was zu optimieren ist auf der C-Seite C? Bei timingkritischen Anwendungen im Bereich weniger Takte? Und oder sogar noch bei solcherart Anwendungen mit Interruptnutzung? Das ist, als wenn du mit einer Flex vom Bau einen Brillianten zu schleifen versuchst... Dafür ist C einfach weder gedacht noch geeignet.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
c-hater schrieb: > Michael W. schrieb: > >> Na ja, in meinem Fall ist die Software so minimal, dass da >> eigentlich kaum was zu optimieren ist auf der C-Seite > > C? Bei timingkritischen Anwendungen im Bereich weniger Takte? Und oder > sogar noch bei solcherart Anwendungen mit Interruptnutzung? > > Das ist, als wenn du mit einer Flex vom Bau einen Brillianten zu > schleifen versuchst... > > Dafür ist C einfach weder gedacht noch geeignet. Ich sehe schon, Dein Name ist Programm... ;-) Ja evtl. beisse ich mal in den sauren Apfel und versuche es direkt! Vorher gucke ich mir aber mal an, was gcc da erzeugt hat. Ich glaube aber nicht, dass das wirklich die Erklaerung fuer die beobachtete "Pin Traegheit" ist.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
> Verwendest Du eine spezielle Beschaltung Nein. Vor den Eingängen liegen (hier unnötige) Schutzwiderstände von 750 Ohm und die Leitungen sind unter 15 cm lang. > Bist Du sicher, dass keine Artefakte auftreten? Ja.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: >> Verwendest Du eine spezielle Beschaltung > Nein. Vor den Eingängen liegen (hier unnötige) Schutzwiderstände von 750 > Ohm und die Leitungen sind unter 15 cm lang. > >> Bist Du sicher, dass keine Artefakte auftreten? > Ja. OK, danke.. das zeigt mir zumindest, dass es prinzipiell moeglich sein muesste, mit Technologie von 2017 auf den Stand von 1968 zu kommen ;-) Ich werde das mal mit einem anderen AVR probieren.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Danke an alle! Ich habe genuegend Ideen / Anregungen erhalten, wo ich weitersuchen kann.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Ich ware mir z.B. nicht sicher, ob ich AVCC and VREF und diese Sachen > beschalten sollte, da ich ja eigentlich keine AD-Wandlung benoetigt. > Evtl. hat das aber Einfluss auf "Pin-Traegheit" oder was auch immer? > Oder alle nicht benutzten PINs auf GND ziehen, ... IMHO muß AVCC immer angeschlossen werden, sonst funktioniert Port C nicht. MfG Klaus
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Klaus schrieb: > IMHO muß AVCC immer angeschlossen werden, sonst funktioniert Port C > nicht. Hallo Klaus, habe ich jetzt ausprobiert, konnte keinen Unterschied in meiner Anwendung beoabachten. Habe nach wie vor Murks im Buffer, nun insbesondere "doppelte" Bytes, also als ob der Interrupt "prellen" würde (bin mir aber ziemlich sicher, dass er das nicht tut - bei PIN Change kann ich das ja verstehen, ein Byte für steigende, eines für fallende Flanke, aber sonst nicht, oder?) Muss also was elektrisches sein, irgendwie. Letzte Programm-Version war (diesesmal keine Skizze, das ist das echte Programm): #include <avr/io.h> #include <util/delay.h> #include "pinDefines.h" #include <avr/interrupt.h> #define BAUD 9600 #include "USART.h" #define SIZE 1024 #define BV(bit) (1 << (bit)) #define toggleBit(byte, bit) (byte ^= BV(bit)) #define setBit(byte, bit) (byte |= BV(bit)) #define clearBit(byte, bit) (byte &= ~BV(bit)) volatile uint8_t buffer_low[SIZE]; volatile uint8_t buffer_high[SIZE]; volatile uint8_t buffer_index = 0; volatile uint8_t last_low = 0; volatile uint8_t last_high = 0; ISR(INT0_vect) { cli(); // _delay_ms(10); last_low = PINB; last_high = PINC; last_low &= 0b00011110; last_high &= 0b00001111; buffer_low[buffer_index] = last_low; buffer_high[buffer_index] = last_high; buffer_index++; sei(); } void initInterrupt(void) { EICRA |= (1 << ISC01); EICRA |= (0 << ISC00); EIMSK |= (1 << INT0); sei(); } int main(void) { DDRB = 0; DDRC = 0b00110000; initUSART(); clearBit(PORTC, 5); clearBit(PORTC, 4); while (receiveByte() != ':'); buffer_index = 0; last_low = 0; last_high = 0; initInterrupt(); while ( 1 ) { setBit(PORTC, 5); if ( buffer_index > 0 && ( last_low == 20 || last_low == 26)) { clearBit(PORTC, 5); setBit(PORTC, 4); cli(); for (int i = 0; i < buffer_index; i++) { uint8_t byte = ( buffer_low[i] >> 1 ) | (buffer_high[i] << 4); transmitByte( byte); } sei(); buffer_index = 0; last_low = 0; last_high = 0; } } return 0; } (PORTC 5 und 4 sind Status-LEDs) Habe erneute fallende und steigende Flanke probiert, und sowohl INT0 als auch INT1, mit und ohne AVCC, mit verschiedenen 328ern - macht alles keinen Unterschied :-( Und, wie gesagt, der Effekt tritt auch auf, wenn ich seeeehr langsam die Bytes sende. Es scheint so, dass der 328 mein Interrupt-Signal nicht mag. Vielleicht ist es zu kurz o.ä, wie gesagt, das Flip Flop hat kein Problem mit dem Signal. Ich weiß ehrlich gesagt nicht, wo da was "Prellen" könnte... (elektrische Reflektionen??) Gruß. Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
PS Mit dieser Variante sind es also nicht nur Bitflips, sonder auch Doppelte im buffer.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ich habe keine Ahnung von C, aber wie funktioniert das: > #define SIZE 1024 > volatile uint8_t buffer_low[SIZE]; > volatile uint8_t buffer_high[SIZE]; der ATmega328 hat doch nur 2 KiB SRAM?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
> volatile uint8_t buffer_low[SIZE]; > volatile uint8_t buffer_high[SIZE]; der ATmega328 hat doch nur 2 KiB SRAM? Danke... guter Hinweis... sollte mich der Compiler da nicht warnen? Ich werde es mal auf 128 bytes oder so runter setzen und gucken, ob es einen Unterschied macht. Das Program macht ja was... und es sendet auch Bytes an den Emic... kann es dennoch sein, dass es "intern korumpiert" ist durch zu großen buffer?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
> Ich habe keine Ahnung von C
kann die Fragen also nicht beantworten. Der avrasm2 brächte für '.dseg'
eine Warnung "OVER", eventuelle Laufzeitfehler hingen von der
Variablenanordnung ab.
Nur am Rande, auch wenn der eine Takt zu Beginn der ISR wohl keine
Rolle spielt: cli/sei zu Beginn/Ende einer ISR sind überflüssig, das
macht die Hardware (schneller und besser).
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Danke... guter Hinweis... sollte mich der Compiler da nicht warnen? ... habe den SIZE buffer auf 16 gesetzt... leider kein Unterschied. Immer noch BitFlips und Doppelte :-(
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: >> Ich habe keine Ahnung von C > kann die Fragen also nicht beantworten. Der avrasm2 brächte für '.dseg' > eine Warnung "OVER", eventuelle Laufzeitfehler hingen von der > Variablenanordnung ab. > Nur am Rande, auch wenn der eine Takt zu Beginn der ISR wohl keine > Rolle spielt: cli/sei zu Beginn/Ende einer ISR sind überflüssig, das > macht die Hardware (schneller und besser). Danke, ja, gelesen hatte ich das, aber in meiner "Verzweiflung" greife ich halt nach jedem Strohhalm ;-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Zusammengefasst: - INT0 scheint zu "prellen" -> Doppelte - PORTB, PORTC sind traege - bits, die vorher 1 waren und nun 0 sein sollten, sind immer noch 1. Das einzige was hilft, ist ein 0 byte zu senden, und etwas zu warten... - AVCC macht keinen Unterschied hier - INT0, INT1, ... macht keinen Unterschied hier - steigende und fallende Flanke erzeugt logischerweise mehr Murks und Doppelte als nur steigende oder nur fallende Flanke, aber auch damit ist Murks im Buffer - wenn ich zu schnell sende, reicht die Interrupt-Bearbeitungsgeschwindkeit nicht aus, und Bytes gehen verloren. Das ist klar, aber nicht das eigentlich Problem hier. - mein 74LS373 Flip Flop hat diese Probleme nicht, und das Datenbyte ist stets korrekt am Ausgang. Dabei kriegt das Flip Flop exact das gleiche Select-Signal, wie INT0. Vielleicht sind meine PINB, PINC Eingaenge irgendwie falsch konfiguriert?? Es ist raetselhaft.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Das 74LS373 verarbeitet ja auch nicht, fragt z.B. nicht auf 20 oder 26 ab - was hat es eigentlich damit auf sich?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Das 74LS373 verarbeitet ja auch nicht, fragt z.B. nicht auf 20 oder 26 > ab - was hat es eigentlich damit auf sich? 20 = 10 (LF) << 1 26 = 13 (CR) << 1 Das ist die Aufforderung, den Buffer an den Emic 2 zu senden. (PINB-Eingang ist um 1 Bit nach link verschoben - um Zeit zu sparen in der Interrupt-Routine, speichere ich die ausmaskierten Ports "raw", also ohne Verschiebung, das mache ich erst beim Senden (das Ausmaskieren kann ich mir wohl auch sparen). Das alles macht zwar die Interrupt-Behandlungsroutine schneller, behebt aber nicht die beiden Grundprobleme: - INT0 prellt (Doppelte) - pins sind traege (Bitflips)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Das heißt, die 'Nutzbytes' haben im unteren Teil nie 0x1a bzw. 0x14? Und warum wird überhaupt ein Zeilenende abgewartet?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Das heißt, die 'Nutzbytes' haben im unteren Teil nie 0x1a bzw. 0x14? Richtig, ich sollte wohl auch auf "last_high == 0" testen im "if", danke ;-) > Und warum wird überhaupt ein Zeilenende abgewartet? ... in erster Linie, um die Interrupt-Behandlung "so schnell wie möglich" zu machen. Ich hatte auch versuche, das empfangene Byte direkt (ungepuffert) rauszusenden, kostet aber natuerlich Zeit. Ob das Abspeichern in 2 Arrays nicht letztlich mehr Zeit kostet, als das konvertierte Byte direkt rauszusenden, weiß ich nicht, ich denke aber nicht (das serielle Senden wird viel länger dauern IMHO). Daher will puffern und das nicht in der INT0-Routine machen. Da Geschwindigkeit wie gesagt nicht das Hauptproblem ist - selbst wenn ich direkt sende, sende ich Murks - Bitflips.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Nun weiß ich erstmal nicht weiter. Das mit den "Bitflips" sieht nach Hardware aus, eingangs- oder auch ausgangsseitig. Wie lang ist eigentlich so eine 'Datenzeile', wie oft kommt eine und wie schnell kommen die einzelnen Bytes?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Nun, der kuerzeste Test fuer "Bitflips" und Doppelte ist sowas wie "s123<CR>" oder "s123<LF>" - ("s" = "speech" ist das "Start-Token" fuer den Emic 2 - der puffert das selbst, und spricht erst wenn er CR oder LF kriegt). Wohlgemerkt, diese ASCII Ziffern haben alle kein & 10 oder & 13 gesetzt. Und dann sagt der Emic dann ab und zu korrekt "onehundredtwentythree", oftmals aber eben auch sowas wie "1223", also "onethousandtwohundredandtwentythree" (-> Doppelte), oder manchmal eben was voellig verqueres (Bitflips) Die Bytes koennen beliebig langsam gesendet werden - ich verwende ein BASIC-Programm, also nicht mehr als 10 Zeichen pro Sekunde oder so.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
< 10 char/s? 9600 Bd sind rund 1000 - da würde ich zum Testen die ganze Buffer-Mimik weglassen; man könnte sogar alles in der INT0-ISR machen, das Byte zusammensetzen und gleich auf den UART (sts UDR0,rn braucht 2 Takte) geben, es muss ja nicht einmal auf UDRE0 abgefragt werden. Die serielle Verbindung zum EMIC ist in Ordnung?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Nun weiß ich erstmal nicht weiter. In jedem Fall - vielen Dank für Deine Hilfe!! Ich denke, ich werde einmal die nächst-größere Variante des AVRs probieren. Dann habe ich 8 Bit am Stück frei. Vielleicht habe ich ja auch eine "Billig-Raubkopie" des AVRs erworben, der irgendwie elektrisch minderwertig ist (gefälschte Chips soll es ja geben). Und nun habe ich davon 5 Stück ;-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > Die serielle Verbindung zum EMIC ist in Ordnung? Oh ja - ich habe ja auch eine funktionierende (wenn auch unschöne) Lösung, s. YouTube-Video oben. Wie gesagt - diese Lösung kommt ohne Interrupts aus, benötigt 0-bytes im Datenstrom, das 8. Bit in den Nutzbytes gesetzt "für Selbsttaktung" (habe ja keinen Interrupt dann), und etwas Wartezeit. Gepuffert wird in der while (1) Hauptschleife. Das funktioniert dann. Ist aber unbefriedigend.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. Landolt schrieb: > < 10 char/s? 9600 Bd sind rund 1000 - da würde ich zum Testen die ganze > Buffer-Mimik weglassen; man könnte sogar alles in der INT0-ISR machen, > das Byte zusammensetzen und gleich auf den UART (sts UDR0,rn braucht 2 > Takte) geben, es muss ja nicht einmal auf UDRE0 abgefragt werden. ... und hier noch mal ein Versuch ohne Buffering - #include <avr/io.h> #include <util/delay.h> #include "pinDefines.h" #include <avr/interrupt.h> #define BAUD 9600 #include "USART.h" #define BV(bit) (1 << (bit)) #define toggleBit(byte, bit) (byte ^= BV(bit)) #define setBit(byte, bit) (byte |= BV(bit)) #define clearBit(byte, bit) (byte &= ~BV(bit)) ISR(INT0_vect) { uint8_t lo_nib = PINB; uint8_t hi_nib = PINC; //_delay_us(100); uint8_t byte = ( ( lo_nib & 0b00011110 ) >> 1 ) | ( ( hi_nib & 0b00001111 ) << 4); transmitByte( byte ); // _delay_us(100); } void initInterrupt(void) { // DDRD &= ~(1 << DDD2); // PORTD |= (1 << PORTD2); EICRA |= (1 << ISC01); EICRA |= (1 << ISC00); EIMSK |= (1 << INT0); sei(); } int main(void) { DDRB = 0; DDRC = 0; _delay_ms(1000); initUSART(); while (receiveByte() != ':'); printString("SSpeech synthesizer ready.\n"); while (receiveByte() != ':'); initInterrupt(); while ( 1 ) { } return 0; } ... was soll ich sagen - klappt auch nicht besser. Die Eingänge im 328 sind für diese Anwendung nicht geeignet, die Signalqualität ist nicht ausreichend, oder die Stromversorgung oder was auch immer. Gruß, Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Im Prinzip bräuchtest du einen Controller mit Slave-Buseingang. Meines Wissens gibt es keinen AVR, der soetwas hat - aber durchaus ein paar PICs. Ohne /WAIT-Signal wirst du vermutlich das Timing nicht einhalten können, und Dummy-Bytes schicken müssen ist auch keine ordentliche Lösung.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. R. schrieb: > Im Prinzip bräuchtest du einen Controller mit Slave-Buseingang. Meines > Wissens gibt es keinen AVR, der soetwas hat - aber durchaus ein paar > PICs. > > Ohne /WAIT-Signal wirst du vermutlich das Timing nicht einhalten können, > und Dummy-Bytes schicken müssen ist auch keine ordentliche Lösung. Timing ist ja eigentlich variabel einstellbar... zumindest liegt das Nutzbyte ja solange am FlipFlop, wie ich es will. Ich muss nur sehen, dass ich das Select-Signal erwische. Anders als der 328 hat das FlipFlop keine Probleme damit, das byte korrekt vom Datenbus zu lesen und zu latchen, wenn mein Selec-Signal kommt. Das Select-Signal brauche ich also nur, um zu wissen, wann ein "neues" Byte fuer mich anliegt. Und anscheinend mag der 328 mein Select-Signal aus unerfindlichen Gruenden nicht. Ich werde jetzt noch mal folgende 2 Sachen probieren, bevor ich den AVR gegen was besseres austausche: - beim Einsprung in die ISR etwas warten, bevor ich die beiden Nibbles von PINB und PINC lese, in der Hoffnung, dass sich die Pegel der PINs dann "stabilisieren" und "einschwingen". Natuerlich setzt das die BAUD-Rate, mit der ich Bytes vom CPC senden kann, etwas herab. Das Select Signal ist kurz - es wird erzeugt von den beiden PLDs, wenn Addresse &FE90 auf dem Addressbus erscheint, und ~IORQ und ~WR runter gehen (~M1 verwende ich nicht). Dann hat der CPC mittles out &fe90,<x> das Byte auf den Datenbus gelegt. Wenn ich das richtig sehe, liegt das Select Signal und das Datenbyte fuer 1 Takt an, das waeren also bei 4 Mhz unter 1 Mikrosekunde. Klar, dass die urspruenglich Idee, das Byte direkt vom Datenbus zu laden mit dem 328 bei Select, illusorisch war. Das FlipFlop kann's aber. - anstatt mein Select-Signal fuer INT0 zu nehmen, werde ich einmal Bit8 vom Datenbyte vom FlipFlop dafuer nehmen. Dann muss ich zwar wieder 0, "Nutzbyte + 8. Bit gesetzt" senden (kein Problem bei 7Bit ASCII), um einen "Takt" auf das 8. Bit fuer den INT0 zu kriegen, aber damit kann ich dann sehen, ob es irgendwie an der QUalitaet des Select-Signals liegt. Das ist dann im Prinzip mein "altes" Protokol, nur mit ISR anstatt busy loop; diese "Loesung" funktioniert wie gesagt wunderbar, s. Video: while (1) { loop_until_bit_is_set(bit8); byte = PINB, PINC lesen buffer[index]=byte if (byte = End of line) ... send to Emic loop_until_bit_is_clear(bit8); } Wenn ich das Einlesen mit dem 8. Bit vom FLipFlop zuverlaessig hinkriege, aber nicht mit dem eigentlichen Select-Signal, muss ich mir das Signal mal genauer mit dem Scope anschauen. Vielleicht kann es ja "elektrisch aufgewertet" werden. Schoene waere es ja schon, wenn ich volle Bytes senden koennte, und keine 0-Bytes braeuchte :-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ohne das Problem genauer eingegrenzt zu haben (hast du dir eigentlich mal deine Signale mit dem Oszi angesehen?) ist es nie verkehrt sich immer die folgenden Fragen zu stellen: Warum sollte ausgerechnet ich unter Millionen Anwendern der Erste sein, der dieses Hardwareproblem mit dem AVR hat? Warum berichtet niemand sonst über dieses Problem? Mit der Konsequenz aus diesen Überlegungen macht man sich dann auf die Fehlersuche…
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > gibt's hier noch mehr Fans vom Schneider (Amstrad) CPC 464? Hatte ich auch einmal, kam nach dem ZX Spectrum. Sich heute damit zu befassen ist so, als ob man mit einer Dampfmaschine spielt. mfg klaus
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Joe G. schrieb: > Ohne das Problem genauer eingegrenzt zu haben (hast du dir eigentlich > mal deine Signale mit dem Oszi angesehen?) ist es nie verkehrt sich > immer die folgenden Fragen zu stellen: > Warum sollte ausgerechnet ich unter Millionen Anwendern der Erste sein, > der dieses Hardwareproblem mit dem AVR hat? Warum berichtet niemand > sonst über dieses Problem? Mit der Konsequenz aus diesen Überlegungen > macht man sich dann auf die Fehlersuche… Da stimme ich zu - in der Hoffnung hatte ich ja hier gepostet, dass einer sagt - "mensch, bevor mit der ISR neu von PINB, PINC lesen willst, musst Du doch die Eingänge reseten", oder "wo ist denn Dein RC-Glied am Pin?". oder was auch immer ;-) Ich bin kein Elektroniker. Wie gesagt - ich halte das, was ich aufgebaut habe, für ein Minimal-Standard-Design und hatte eigentlich solche Probleme nicht erwartet. Etliche Hardware-Erweiterungen in den 80er für den CPC wurden genau so aufgebaut. OK, Select-Signal hat man in den 80er mit 74x... gemacht, das Signal sollte / dürfte nicht wesentlich anders aussehen, mit PLDs. Ich gebe zu bedenken, dass das Flip Flop kein Problem mit der Schaltung hat - nur der 328. Ich will den 328 nicht schlecht machen, ich finde es halt rätselhaft, was da mit den Eingängen vor sich geht. Ja, ich habe mir das Select-Signal mal angesehen mit dem Scope - es ist halt sehr kurz! Aber ich kann nichts abwegiges daran feststellen. Ich kann ja mal einen Screenshot posten demnächst. Danke für den Input, Gruß Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Klaus R. schrieb: > Hatte ich auch einmal, kam nach dem ZX Spectrum. Sich heute damit zu > befassen ist so, als ob man mit einer Dampfmaschine spielt. > mfg klaus Warum auch nicht, wenn's Spaß macht - man muss ja auch ein Hobby haben :-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Ja, ich habe mir das Select-Signal mal angesehen mit dem Scope - es ist > halt sehr kurz! Aber ich kann nichts abwegiges daran feststellen. Ich > kann ja mal einen Screenshot posten demnächst. Stichwort Puls-Breite - weiß hier einer, wie lang der Puls sein muss, damit 328 überhaupt zwischen fallender und steigender Flanke sauber unterscheiden kann? Ist garantiert, dass steigende vor fallender kommt, wenn der Puls sehr kurz ist? Wie gesagt - das INT0 scheint mir "zu prellen".
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ich wollte noch einmal ein Update in dieser Angelegenheit senden - - die Pulsbreite vom Select-Signal ("IO-Adresse erkannt") beträgt 1,8 uS - die maximale Geschwindigkeit, mit der Bytes gesendet werden per BASIC, beträgt 840 uS (mit Z80 Assembler ginge es schneller) Das sollte eigentlich locker reichen, um auf den Interrupt zu reagieren. Am Wochende habe ich folgendes ausprobiert: - statt des FlipFlops und parallelem Auslesens des Bytes habe ich einmal einen 74HC165 parallel-2-seriell Schieberegister verwendet. Load wie gehabt mit dem Select-Signal ("Adresse erkannt"), lesen über PB1, takten zum Auslesen über PB2 und PB3. Interessanterweise erzeugt auch das Bitfehler!! Es liegt also nicht am parallelen Auslesen mit dem 328. Das serielle Auslesen ist ebenfalls fehleranfällig :-( - dann dachte ich, so, vielleicht hatte ich ja den Datenbus und das FlipFlop zu früh "frei gesprochen", und die Daten sind wirklich nicht astrein auf dem Bus... also spendierte ich dem Aufbau noch einen 74HC244 - zu meiner Frustration hat auch das nichts verbessert.. ich kriege immer noch eigenartigen Murks im Buffer. - ich habe auch noch ~M1 vom Z80 in das Select-Signal einfließen lassen, es machte aber keinen Unterschied (ich dachte mir, vielleicht wir das Signal "zu oft" ausgelöst - so ist die Bedingung nun &F9Ex & ~WRT & ~IORQ & M1) - M1 macht keinen Unterschied. - ich habe mehrere Sieb-Kondensatoren eingebaut - kein Unterschied. - dann habe ich noch am Program was geändert - u.a. hatte ich gelesen, dass das INT0 Flag gesetzt werden kann, auch innerhalb der ISR, und das nach Rückkehr aus der ISR sofort wieder die ISR - wenn Flag zwischenzeitlich gesetzt wurde - angesprungen werden kann, wenn man nicht das Flag-Register mittels EIFR = (1 << INTF0); löscht. Das hätte natürlich "doppelte Bytes" erkären können. Har allerdings keinen wesentlichen Unterschied gemacht. - auch habe ich natürlich erneut mit dem Timing gespielt. Selbst mit langsamsten Einstellungen (Senden von einem Zeichen per Byte und entsprechende großzügigen Wartezeiten im AVR-Code) habe ich die fehlerhaften Bytes nicht vollständig eliminieren können. - ich habe inzwischen auf mehren Web-Seiten gelesen, dass die AVR-Eingänge eigentlich keine echten "Digital-Eingänge" sind, sondern analoge Eingänge sind. Und dass die TTL- bzw CMOS-Kompatibilität nur bedingt gegeben ist. Kann das hier der Fall sein? Wie kommt es dann, dass meine busy-Loop-Polling Lösung perfekt funktioniert? Ich muss sagen, dass ich mit meinen Ideen inwzischen einigermaßen am Ende angelangt bin :-) Ich habe mit mal einen PIC bestellt. Ich bin gespannt, und ich damit ähnliche Probleme habe. Ich habe die Signale mit dem Oszi angeschaut, und es sieht eigentlich alles gut gut.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
... und ansonsten hoffe ich auf mein PCB. Vielleicht funktioniert es damit ja, wenn die fliegenden Leitungen beseitigt sind...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
So viel Aufwand um einen MK3801 nach zu bauen ;) Noch sind die beiden für $6,78 aus Irland zu haben.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
pegel schrieb: > So viel Aufwand um einen MK3801 nach zu bauen ;) Richtig.. aber für den MK3801 benötigt ich Treiber-Software auf dem CPC... während ich mit meiner Lösung einfach "out &F9Ex, <byte>" in BASIC senden kann ;-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Treiber-Software Na ja, ich habe mir den Treiber jetzt nicht genau angesehen, aber ich denke das der darin besteht einige Register zu setzen bevor die Nutzdaten ausgegeben werden. Das ist sicher auch in Basic möglich.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Gerade noch mal rein gesehen. Ist schon ein richtiger Treiber der 3 Basic Befehle erzeugt. Scheint recht übersichtlich zu sein und wirklich hauptsächlich E/A Befehle abzusetzen. Meine Z80 Zeiten sind aber zu lange her für ein schnelles Verständnis der Befehle :(
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ja, es ist sicherlich nicht super schwierig das hinzubekommen, allerdings hätte die uC-Lösung den Charme, dass ich damit ein wiederverwendbares Schema hätte, um eigentlich beliebige Hardware am CPC anzuschließen. Insofern "hänge" ich an der Lösung.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Na gut ;)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Joe G. schrieb: > Warum sollte ausgerechnet ich unter Millionen Anwendern der Erste sein, > der dieses Hardwareproblem mit dem AVR hat? Warum berichtet niemand > sonst über dieses Problem? Mit der Konsequenz aus diesen Überlegungen > macht man sich dann auf die Fehlersuche… Zu dieser Aussage mal eine Nachfrage - bisher habe ich ein Projekt gefunden, wo einer mit dem atmega 328 was vom Z80 Bus liest bzw. Flip Flop: https://hackaday.io/projects/hacker/623 In der Tat habe ich mich jetzt einmal mit dem Autor ausgetauscht - und zu meiner Ueberraschung stellte ich fest, dass er ebenfalls mit Polling in der Busy-Loop arbeitet, da er ebenfalls Probleme hatte mit Lesen in der ISR... Coincidence? Ueber weitere Pointer auf vergleichbare Projekte (immerhin muss es doch schon einige hundertausende AVR-Nutzer geben, die genau das gemacht haben) wuerde ich mich super freuen :-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Das Problem ist, dass ein Z80 @ 4 MHz den AVR ohne Probleme überrennen kann, weil der AVR kein natives Businterface hat. Mit Polling kannst du kürzere Reaktionszeiten erreichen als mit Interrupts, was aus meiner Sicht hier das Problem ist. In meinem System hatte der AVR ein "AUTOWAIT"-Signal, welches - wenn aktiv und der AVR angesprochen wird - automatisch /WAIT zieht. Das war auch notwendig, da ich den Z80-Bus per I2C angebunden hatte.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Die Nutzung von /WAIT scheint mir die korrekte Lösung für das Problem zu sein, zumal Das Wait-Signal genau dafür konzipiert wurde.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > ... was soll ich sagen - klappt auch nicht besser. > Die Eingänge im 328 sind für diese Anwendung nicht geeignet, > die Signalqualität ist nicht ausreichend, oder die Stromversorgung > oder was auch immer. Dafür gibt es ja exakte Spezifikationen für die Chips, besonders Bus/IO/Pegel/Timing etc. So ganz verstehe ich das Problem nicht. Bei den alten Prozessoren muß/te man immer die sehr schwachen Bustreiber berücksichtigen. Um einen fetten AVR-Port umzuladen, brauchen die vielleicht etwas mehr Zeit als man denkt.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ich habe inzwischen meine Busy-Polling-Loop mal so umprogrammiert, dass PD2 nicht als INT0 verwendet wird, sondern einfach als "naechstes Byte ist verfuegbar" Flag; Skizze: while (1) { do { loop_until_bit_is_set(PORTD, 2); byte = read PINB, PINC buffer[index++] = byte; } while ( byte != 13); send buffer to Emic } Das scheint zu 95% zu funktionieren. Damit brauche ich also keine 0-Bytes mehr im Datenstrom, und auch kein 8. Bit gesetzt in den Nutzdaten; ich kann also einfach das Select-Signal ("IO-Addresse erkannt") verwenden. Insofern ist das Protokoll auf CPC-Seite also so einfach wie moeglich - ein "out &f9ex, <byte>" Befehlen reicht, um <byte> zu senden. Danke fuer die Ideen... READY / WAIT Signal wollte ich ja immer vermeiden. Tatsaechlich ist es moeglich, den CPC in den Wartezustand zu versetzten, wenn ich READY / WAIT auf GND ziehe. Allerdings - ich brauche dafuer ja tristate bzw. einen hochohmigen 328 Ausgang. Wenn ich READY auf VCC ziehe, schmiert der CPC natuerlich sofort ab... ich brauche also die beiden Zustaende "nicht verbunden (hochohmig) und 0 (GND)". Dafuer habe ich nur diese Loesung gefunden; hochohmig: PIND = 0; (INPUT) 0 (GND): DDRD = 0b00001000; (ich verwende PD3) clearBit(PORTD, 3); m.a.W., um Tristate hinzukriegen mit den 328, muss ich den Pin zwischen Input und Output-Konfiguration toggeln. Wenn ich das in der Busy Loop oben mache, kriege ich wieder Murks in den Eingaengen...!! Evtl. dauert diese Operation zu lange, oder die Eingaenge werden sonstwie elektrisch korrumpiert. Gibt es eine bessere Loesung, um einen Pin in den hochohmigen Ausgangs-Zustand zu versetzen?
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ich glaube, der folgene Artikel ist genau richtig für dein Problem: https://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Joe G. schrieb: > Ich glaube, der folgene Artikel ist genau richtig für dein Problem: > https://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen Danke für den Hinweis, allerdings erschließt sich mir die Relevanz nicht unmittelbar. Willst Du mir damit sagen, dass: a) ich Assembler verwenden soll, b) sicherstellen soll, dass ich ein NOP oder eine sonstige Warte-Operation zwischen Wechsel von Eingang auf Ausgangs-Modus für PD3 benötige (das ist in der Tat neu für mich!) c) ... ? Ich weiß über den PullUp-Widerstand Bescheid für Eingänge; im Artikel kann ich keinen Hinweis darauf entdecken, wie man einen Ausgang zwischen Hochohmig (nicht verbunden) und Low (GND) toggelt, ohne den Modus zwischen Input / Output zu toggeln? Danke und mfG Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ich wollte eigentlich auf diese Stelle hinweisen. Vorsicht! In bestimmten Situationen kann es passieren, dass scheinbar Pins nicht richtig gelesen werden. Speziell bei der Abfrage von Matrixtastaturen kann der Effekt auftreten, dass Tasten scheinbar nicht reagieren. Typische Sequenzen sehen dann so aus: ldi r16,0x0F out DDRD,r16 ; oberes Nibble Eingang, unteres Ausgang ldi r16,0xFE out PORTD,r16 ; PD0 auf 0 ziehen, PD4..7 Pull ups aktiv in r17,PIND ; Pins lesen schlägt hier fehl! Warum ist das problematisch? Nun, der AVR ist ein RISC-Microcontroller, welcher die meisten Befehle in einem Takt ausführt. Gleichzeitig werden aber alle Eingangssignale über FlipFlops abgetastet (synchronisiert), damit sie sauber im AVR zur Verfügung stehen. Dadurch ergibt sich eine Verzögerung (Latenz) von bis zu 1,5 Takten, mit der auf externe Signale reagiert werden kann. Die Erklärung dazu findet man im Datenblatt unter der Überschrift "I/O Ports - Reading the Pin Value".
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > b) sicherstellen soll, dass ich ein NOP oder eine sonstige > Warte-Operation zwischen Wechsel von Eingang auf Ausgangs-Modus für PD3 > benötige (das ist in der Tat neu für mich!) Joe G. schrieb: > Dadurch ergibt sich eine > Verzögerung (Latenz) von bis zu 1,5 Takten, mit der auf externe Signale > reagiert werden kann. Die Erklärung dazu findet man im Datenblatt unter > der Überschrift "I/O Ports - Reading the Pin Value". Ja, danke, das habe ich gelesen, dass war mein Punkt b) oben - wie gesagt, war mir nicht bewusst! Ich werde sehen, dass ich das berücksichtige. Wahrscheinlich ist der C-Code ohnehin suboptimal genug um das automatisch zu gewährleisten ;-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
... evtl muss ich in den sauren Apfel beißen, und noch einen weiteren Baustein mit Tristate-Ausgang spendieren... grmmpff...
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Um es noch mal deutlicher zu sagen - nach dem hilfreichen Hinweis von Joe auf mögliche Lesefehler beim Wechseln zwischen Input und Output-Modus eines Pins / Ports, ist meine aktuelle Frage also: gibt es was besseres, um einen Ausgang zwischen hochohmig und 0 (GND) zu toggeln, als hochohmig: PIND = 0; (INPUT) 0 (GND): DDRD = 0b00001000; (ich verwende PD3) clearBit(PORTD, 3); Gruß und danke, Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Ich möchte mich bei allen für die tatkräftige Unterstützung bedanken! Auch wenn das Rätsel um die nicht funktionierende ISR-Lösung nie ganz aufgeklärt worden konnte (ich habe doch ein FlipFlop, verdammt!!), haben doch eine Reihe von Änderungen dazu geführt, dass ich nun eine 100% funktionierende Polling-Busy-Loop habe. Ich möchte die Lösung nicht vorenthalten:
1 | int main(void) { |
2 | |
3 | DDRB = 0; |
4 | DDRC = 0b00110000; |
5 | |
6 | while (1) { |
7 | |
8 | length = 0; |
9 | |
10 | // Status LEDs
|
11 | clearBit(PORTC, 4); |
12 | setBit(PORTC, 5); |
13 | |
14 | do { |
15 | |
16 | DDRB = 0; // enable Z80 READY pin (Tristate not connected) |
17 | |
18 | do { |
19 | pinb = PINB; |
20 | pinc = PINC; |
21 | while (bit_is_clear(PIND, 2)); |
22 | |
23 | do { |
24 | pinb = PINB; |
25 | pinc = PINC; |
26 | } while ( bit_is_set(PIND, 2)); |
27 | |
28 | pinb &= 0b00011110; |
29 | pinc &= 0b00001111; |
30 | |
31 | //pull Z80 pin ready low
|
32 | DDRB |= 1; |
33 | clearBit(PORTB, 0); |
34 | |
35 | buffer_lo[length] = pinb; |
36 | buffer_hi[length] = pinc; |
37 | length ++; |
38 | |
39 | } while ( pinb != 26 || pinc != 0 ) ; |
40 | |
41 | // Status LEDs
|
42 | |
43 | clearBit(PORTC, 5); |
44 | setBit(PORTC, 4); |
45 | |
46 | // send to Emic-2
|
47 | |
48 | if (length > 0) { |
49 | for (int i = 0; i < length; i++) { |
50 | buffer_lo[i] = ( buffer_lo[i] >> 1 ) | ( buffer_hi[i] << 4); |
51 | }
|
52 | buffer_lo[length] = 0; |
53 | printString(buffer_lo); |
54 | }
|
55 | |
56 | clearBit(PORTC, 4); |
57 | |
58 | }
|
59 | |
60 | return 0; |
61 | |
62 | }
|
PB0 ist nun mit dem ~READY-Signal der Z80-Cpu verbunden. Das Timing scheint selbst mit Flip Flop so delikat zu sein, dass selbst Code-Fragmente wie
1 | loop_until_bit_is_set(PIND, 2); |
2 | //pull ready READY immediately
|
3 | DDRB |= 1; |
4 | clearBit(PORTB, 0); |
5 | |
6 | pinb = PINB; |
7 | pinc = PINC; |
8 | |
9 | ....
|
dazu führen, dass pinb, pinc NICHT das korrekte Byte haben, obwohl das FlipFlop dieses Byte auf unbestimmte Zeit latched. Das mag zu tun haben mit dem im AVR-Tutorial beschriebenen Effekt, dass die Eingänge intern FlipFlops sind, und da der Select-Puls (PIND, 2) extrem kurz ist (1,8 uS), dass dann evtl. durch Clock-Versatz das Byte in den PINB, PINC Ports entweder der Input / das Byte vor oder nach dem Clock-Signal anliegt, mit einer evtl. Differenz von 1.5 Takten. Dabei ist es unerheblich, ob das externe FlipFlop den Wert auf unbestimmte Zeit speichert... der Versatz tritt ja trotdem auf bzgl. des Select-Signals (PIND, D). Das macht die Synchronisation mit C fast unmöglich, selbst wenn man ein FlipFlop hat - man weiß nie, ob man nun das Byte 1,5 Takte zu früh oder zu spät gelesen hat. Zumindest ist das meine Erkärung, warum diese Lösung zu 100 % funktioniert:
1 | |
2 | do { |
3 | pinb = PINB; |
4 | pinc = PINC; |
5 | } while (bit_is_clear(PIND, 2)); |
6 | |
7 | do { |
8 | pinb = PINB; |
9 | pinc = PINC; |
10 | } while ( bit_is_set(PIND, 2)); |
11 | |
12 | pinb &= 0b00011110; |
13 | pinc &= 0b00001111; |
14 | |
15 | //pull ready low immediately
|
16 | DDRB |= 1; |
17 | clearBit(PORTB, 0); |
Vielen Dank an Alle - ich muss sagen, dass ich noch nie so viel "Trial and Error" für ein Projekt gebraucht habe, wie für dieses....
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
... ein letztes Update in diesem Thread - inzwischen ist auch mein PCB-Prototyp fertig. https://youtu.be/4YQeXAbyAOA Gruss, Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
... ich wollte mich in dieser Sache noch einmal abschliessend melden... so wie es aussieht, ist all die Diskusion um Timing- und Port-Lese-Probleme etc. Makulatur. So wie es jetzt aussieht, war all dies durch ein Problem in der Adress-Dekodierungs-Logik verursacht - ein falsch beschaltetes UND-Gatter; das C-Programm oben war also ein Workaround (bzw. Red Herring). Inzwischen ist dieses Problem behoben, und der DIY CPC-Sprachsynthesizer hat seine endgueltige Form erreicht ("LambdaSpeak"). https://youtu.be/ckCTHi5_2f8 Falls jemand den Amstrad / Schneider SSA-1 Sprachsynthesizer kennt - dieser kann ebenfalls emuliert werden durch LambdaSpeak: https://youtu.be/PJCfPbCQvmo https://youtu.be/WbvsnRWKF0s https://youtu.be/aTxufTKfrYk An dieser Stelle vielen Dank an alle fuer die Hilfe!! Gruss, Michael
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > ... ich wollte mich in dieser Sache noch einmal abschliessend melden... > so wie es aussieht, ist all die Diskusion um Timing- und > Port-Lese-Probleme etc. Makulatur. Kannst du mal testweise einen String schnellstmöglich an deinen Synthesizer schicken (also mehrfaches LDI), und schauen, ob dein AVR hinterherkommt? Deine Schaltung präsentiert dem AVR ja das zuletzt gesendete Byte, bis ein neues Byte reinkommt. Wenn sich die Z80-Software also genug Zeit nimmt, passt das - interessant ist es aber, ob der AVR die Daten auch im worst case wegspeichern kann.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. R. schrieb: > Deine Schaltung präsentiert dem AVR ja das zuletzt gesendete Byte, bis > ein neues Byte reinkommt. Wenn sich die Z80-Software also genug Zeit > nimmt, passt das - interessant ist es aber, ob der AVR die Daten auch im > worst case wegspeichern kann. Ja, gutes Experiment! Kann ich mal machen. In BASIC braucht man keine Warteschleife einbauen, da kommt der AVR locker mit. Zudem ist der AVR momentan gerade so programmiert, dass er den Z80 anhaelt, bis das Byte weggepuffert wurde, und er wieder empfangsbereit ist. So kann also nichts verloren gehen. Buffer-Ueberlauf wird so ebenfalls verhindert (Buffer wird gesprochen, wenn er voll ist). Das funktioniert natuerlich ebenfalls in Maschinensprache. Fuer einen Bandbreiten-Test kann ich diese Warte-Logik mal rausnehmen und dann schauen. Im SSA-1-Kompatibilitaetsmodus gibt es eine etwas andere Loesung, ich wollte ja (weitgehend) kompatibel zum SSA-1 Sprachsynthesizer sein - hier fragt die Z80-Software den IO-Port per Polling ab, der SPO256 hat dazu 2 Signale / Pins (BUSY and READY o.ae.) Also ohne dass der Z80 angehalten wird.
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
Michael W. schrieb: > Zudem ist der AVR > momentan gerade so programmiert, dass er den Z80 anhaelt, bis das Byte > weggepuffert wurde, und er wieder empfangsbereit ist. Wie machst du das? Ziehst du /WAIT, wie wir das im Thread vorher diskutiert hatten? Michael W. schrieb: > hier fragt die Z80-Software den IO-Port per Polling ab, Okay, wenn du ein langsames Device nachbildest, muss deine Nachbildung auch nicht unbedingt schneller sein. :-)
Re: ATMega328-basierter Sprach-Synthesizer für den CPC 464 - Schnelles Byte-weises Lesen mit dem 328
S. R. schrieb: > Michael W. schrieb: >> Zudem ist der AVR >> momentan gerade so programmiert, dass er den Z80 anhaelt, bis das Byte >> weggepuffert wurde, und er wieder empfangsbereit ist. > > Wie machst du das? Ziehst du /WAIT, wie wir das im Thread vorher > diskutiert hatten? Genau :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.