Forum: Mikrocontroller und Digitale Elektronik Letzter Hilferuf AT91SAM7S - PWM oder PCK


von Peter P. (uncle-sam7)


Angehängte Dateien:

Lesenswert?

Hallo Newsgroup,

ich habe ein Problem:
Irgendwie habe ich mich in mein Projekt "SID-Player mit einem echten 
SID" sehr verbissen. Ich möchte das gerne zu Ende bringen.

genauere Problembeschreibung:
a) ich habe von Elektronik nicht viel Ahnung.
b) ich finde keine für mich verständlichen Beispiele, wie ich mit meinem 
AT91SAM7S ein 1MHz Signal für den SID erzeugen kann. Bislang denke ich, 
dass man das entweder über PWM machen kann oder über PCK. Die Anleitung 
habe ich mir zu diesem Thema angesehen und nicht verstanden.
b) ich möchte nur ungerne zusätzlich einen 1MHz Oszillator "verbraten", 
wenn doch der AT91SAM7S in der Lage ist, so ein Signal zu erzeugen.

Momentan ist das einzige, was mir noch fehlt die beiden 
Bypass-Kondensatoren für VCC und VDD und der Takt (siehe Foto (ohne 
Pin-Verbindungskabel)). Für die Adress-, Daten- und Steuerleitungen habe 
ich mir Verbindungskabel für die Stiftleisten gelötet.

Was bereits funktioniert:
- 6510 Emu
- "einfache" SID-Emu per Software (allerdings ohne Filter). Diesen "Ast" 
werde ich auch nicht weiterentwickeln, da ich nicht denke, dass der ARM7 
das mit Filtern in 44KHz schafft.
- die Schnittstelle zum SID sollte nach erfolgreicher Taktgenerierung 
nur noch "Formsache" sein.
- SIDs werden bereits "sachgemäß" ausgeführt.

Also Ihr seht schon: viel ist es nicht mehr. Ich würde den Takt so gerne 
über PWM oder PCK erzeugen, aber ich check das einfach nicht. Zudem habe 
ich leider kein Oszilloskop, womit ich irgendwas messen könnte.

Deswegen hier nochmal ein allerletzter Aufruf an alle AT91SAM7S-Gurus da 
drausen: Bitte postet ein kleines Beispiel, mit dem auf irgend einem der 
möglichen PINS ein 1 MHz Signal ausgegeben wird, mit dem ich den SID 
takten kann. Vielen Dank schon jetzt für jedes Beispiel! Danke.

In der Hoffnung auf Hilfe
Peter

PS1.: Was ich mir als "Entlohnung" vorstellen könnte wären ein paar 
Greetings im LCDisplay im Bereich "info" :-)

PS2.: Das ist kein kommerzielles Projekt.

von Stephan W. (sir_wedeck)


Lesenswert?

Hi

hast du es schon mit dem PCK(x) probiert, diese Pins wo man den Clock 
raus führen kann?

wie genau brauchst du die 1MHz ???
wenn 1,152 MHz auch noch geht versuch es doch mal.

Für jeden Ausgang gib's ein PMC_PCK(x) Register, dort die Clock Source 
auswählen.
zB.: Main Clock -> 18,432 MHz
Dann einen Vorteiler -> 16 wählen.

Das Reg. PMC_SCER sollte 0x00000001 oder mit USB 0x00000081,
die PCK(0..2) sind die Bits 8..10 .
Ein Bit auf eins setzen, dann ist der Ausgang aktiviert.

Dies sollte eine Frequenz von 1,152 MHz ergeben und auch am 
entsprechenden Ausgang anliegen.

Stephan

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Stephan,

Das hört sich schon mal ganz gut an. Allerdings bin ich mir nicht ganz 
sicher. Das wären ja rund 10% mehr. Nachdem diese Frequenz dann auch als 
Grundlage für die Ausgabe dient, denke ich nicht, dass das sehr gut ist. 
Es werden ja alle möglichen Dinge aufgrund dieser Frequenz berechnet. Um 
dann wieder alles geradezuziehen, müsste ich die 6510 Emu auch 10% 
schneller laufen lassen. Ich denke, dass das leider keine gute Lösung 
ist. Bedeutet das im Umkehrschluss, dass es über PCK nicht genauer geht?

MfG
Peter

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,

ok, wie sieht es bei dir mit der PLL Frequenz aus???
Diese kann ja ebenfalls als Source dienen.

Eine von beiden möglichen Quellen sollte ein vielfaches von den 1 MHz 
sein.
wenn du einen Quarz von 16 MHz verwenden kannst hast du deine 1 MHz im 
Handumdrehen

Stephan

von Stephan W. (sir_wedeck)


Lesenswert?

noch die Teiler vergessen: 1 bis 64

Stephan

von Marvin S. (demo)


Lesenswert?

Ich bin kein SAM7-Profi, aber wieso verwendest du nicht einen Timer 
Counter im Waveform mode?

Gruesse

Marvin

von Peter P. (uncle-sam7)


Lesenswert?

naja, ich denke ich verwende die Möglichkeiten nicht, weil ich es 
einfach nicht begreife...

von Marvin S. (demo)


Lesenswert?

Schau dir mal in "AT91SAM7S Series Preliminary" das Kapitel 33.5.11.2 
an. Da ist das recht schoen beschrieben, wie es imho gehen sollte.

Alternativ hat natuerlich Stefan W. auch recht - ich hatte nur schon von 
vornerein gedacht, du haettest keinen passenden vielfachen Takt. Mit 
welcher Frequenz betreibst du den uC?

Gruesse

Marvin

von Stephan W. (sir_wedeck)


Lesenswert?

Morgen,
also ich glaub das bekommen wir hin!

Wie sind denn deine Clocks ???
Hast du einen Timer frei ???

Stephan

von Peter (Gast)


Lesenswert?

Hallo Stephan,

also Timer verwende ich eigentlich noch keinen. Mein externer Oszillator 
hat 18,xxx MHz ( siehe Bild :-) ). Intern wird das dann soweit ich weiß 
auf 48 MHz multipliziert.

Wenn Du Timer sagst: wird das eine Lösung, die den ARM sehr belastet. 
Ich frag nur, weil wenn der alle paar "Mikroaugenblicke" von einem 
Timerinterrupt unterbrochen wird, bleibt vielleicht nicht mehr genügend 
Zeit für die 6510 EMU? Oder läuft der Timer "nebenher"?

Von der Pinbelegung am ARM bin ich eigentlich auch sehr offen. Ich würde 
alle anderen Dinge nach der "Taktlösung" anpassen.

Viele Grüße und vielen danke, dass Du Dich überhaupt damit beschäftigst. 
Dank natürlich auch an alle anderen, die zur Lösung beitragen.

Gruß
Peter

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,
bei dieser Geschichte brauchst du keinen Interrupt das macht der Timer 
alles alleine!
also fangen wir an einen Timer einzustellen.
Was haben wir:

- Main-Clock -> 18,432 MHz
- 3 Timer zur Verfügung -> wir nehmen T0 Pin TIO_A
- 5 Interne Taktquellen:
1 T = 1 Takt -> Counter inc um 1
max 65535 Takte möglich
1
TIMER_CLOCK1   MCK/2   9,216 MHz  -> 1 T = 108,5 ns  -> 0xFFFF T =   7,1 ms
2
TIMER_CLOCK2   MCK/8   2,304 MHz  -> 1 T = 434,0 ns  -> 0xFFFF T =  28,4 ms
3
TIMER_CLOCK3   MCK/32    576 KHz  -> 1 T =   1,7 us  -> 0xFFFF T = 113,8 ms
4
TIMER_CLOCK4   MCK/128   144 KHz  -> 1 T =   6,9 us  -> 0xFFFF T = 455,1 ms
5
TIMER_CLOCK5   MCK/1024   18 KHz  -> 1 T =  55,5 us  -> 0xFFFF T =   3,6 s
soll Frequenz ist 1 MHz: 1/F = 1 us
Demnach können wir TIMER_CLOCK1 oder TIMER_CLOCK2 als Quelltakt wählen.
wir nehmen TIMER_CLOCK1, da bessere Auflösung!

 1 us / 108,5 ns = 9,2

 9  * 108,5 ns = 976,5 ns -> 1,024 MHz
 10 * 108,5 ns = 1,085 us -> 0,921 MHz

Wir müssen den Timer also bis 9 Zählen lassen.

- Waveform: siehe Punkt 33.5.11.2 im DB
 WAVSEL = 10 -> zählt von Null bis RC (unsere 9)
 Hier können wir den Counter bis zu unseren Wert 9 laufen lassen.
 Der Counter setzt sich selbst wieder zurück und fängt von vorne an.

Da bis jetzt noch nichts geschaltet wird, müssen wir noch die Schwelle 
aktivieren.
Dazu wird das RA Reg verwendet, um nun die Frequenz abzubilden müssten 
wir 9 / 2 verwenden,
da dies aber nicht geht, würde ich 5 oder 4 vorschlagen. (RA = 4) ;-)
Daraus ergibt sich also das entweder das Low- oder das High-Signal etwas 
größer ist!!!! (um 108,5 ns)

Jetzt solltest du noch die Polarität bestimmen, wann ist der Pin Low und 
High.
Dazu gibs die Reg.: (siehe Punkt 33.5.11.2 im DB)
- ACPA, RA Compare Effect on TIOA -> zB: SET Pin
- ACPC, RC Compare Effect on TIOA -> zB: CLEAR Pin

Ich hoffe ich hab nichts vergessen.

Stephan

von Peter P. (uncle-sam7)


Lesenswert?

Das ist grandios. Werde das in einer ruhigen Minute ausprobieren.

Vielen Dank!

von Peter P. (uncle-sam7)


Lesenswert?

...eine Frage noch:

Es gibt ja - so glaube ich - ein Statusregister zu den Pins. Kann ich 
das verwenden, um zu sehen, ob der Pin gerade High oder Low ist.

Weil ich sollte ja im Idealfall einen Zustandswechsel abwarten und "von 
dort aus" meine Daten übertragen. Dann bis zum nächsten Wechsel warten 
und fertig...

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,
Status Regs. gibt es.
Ist dein Programm wirklich so schnell???
Im schlimmsten Fall, liest du Pin ist High und das wiederholt sich und 
du kommst nicht aus der Schleife. (da das Auslesen immer zum gesetzten 
Level passiert)

ich würde es so machen:
lese TC Status Register, schmeiße das Ergebnis weg.
dann so lange lesen bis RA Compare Status oder RC Compare Status wieder 
gesetzt ist.
Wobei ich zum RC tendieren würde.
RA wäre dein Flankenwechsel und RC eine Periode.

Stephan

von Frank B. (foobar)


Lesenswert?

Peter Pippinger schrieb:
> ich habe ein Problem:
> Irgendwie habe ich mich in mein Projekt "SID-Player mit einem echten
> SID" sehr verbissen. Ich möchte das gerne zu Ende bringen.

Sehr lobenswert. Ich fange viel zu viel Hobbyprojekte an, die ich dann 
nicht zuende bringe.

> genauere Problembeschreibung:
> a) ich habe von Elektronik nicht viel Ahnung.
> b) ich finde keine für mich verständlichen Beispiele, wie ich mit meinem
> AT91SAM7S ein 1MHz Signal für den SID erzeugen kann. Bislang denke ich,
> dass man das entweder über PWM machen kann oder über PCK. Die Anleitung
> habe ich mir zu diesem Thema angesehen und nicht verstanden.
> b) ich möchte nur ungerne zusätzlich einen 1MHz Oszillator "verbraten",
> wenn doch der AT91SAM7S in der Lage ist, so ein Signal zu erzeugen.

Wenn es dein Hauptziel ist, den SID zum laufen zu bringen, wäre die 
einfachste Lösung erstmal tatsächlich noch einen externen 1 MHz 
Quartzoszillator zu verwenden. Sowas hat man normalerweise in der 
Bastelkiste rumliegen :-)

> Momentan ist das einzige, was mir noch fehlt die beiden
> Bypass-Kondensatoren für VCC und VDD

Das könnte schon wichtig sein. Falls du mehr mit Elektronik machen 
willst, würde ich dir empfehlen, ein paar Bauteile auf Vorrat zu kaufen, 
also z.B. ein Widerstandsortiment und ein paar oft verwendete 
Keramikkondensatoren und ggf. Elkos. Braucht man immer wieder.

> Also Ihr seht schon: viel ist es nicht mehr. Ich würde den Takt so gerne
> über PWM oder PCK erzeugen, aber ich check das einfach nicht. Zudem habe
> ich leider kein Oszilloskop, womit ich irgendwas messen könnte.

Ohne Oszilloskop wirst du nicht viel Spaß mit 
Microcontrollerentwicklungen haben, zumindest nicht wenn es was 
komplizierter wird mit schnellen Signalen, z.B. wenn du später mal die 
Steuerleitungen zum SID messen willst oder irgendwann mal I2C oder SPI 
debuggen willst. Ich habe z.B. das hier und bin da sehr zufrieden mit:

http://www.reichelt.de/?ARTICLE=84986

Die Software dazu ist kostenlos und seit der neuesten Version 
funktioniert sogar die Triggerfunktion vernünftig, sodaß ich mein 
Tektronix kaum noch verwende.

von Peter P. (uncle-sam7)


Lesenswert?

Frank Buss schrieb:
>> Momentan ist das einzige, was mir noch fehlt die beiden
>> Bypass-Kondensatoren für VCC und VDD
>
> Das könnte schon wichtig sein. Falls du mehr mit Elektronik machen

"Schon wichtig"

im Sinne von: da kann was kaputt gehen?
oder eher
im Sinne von: da kommen evtl. fehlerhafte Signale beim SID an?

...werde jetzt mal das mit der Taktung probieren...

von Peter P. (uncle-sam7)


Lesenswert?

Hallo

So, jetzt habe ich das mit dem Takt mal erfolglos probiert.
Mein Ziel wäre erst mal, den Timer zu starten. Dann möchte ich gerne 
zwischen meinen LED-blinkern eine Schleife haben, die so lange wartet, 
bis der Takt neu beginnt. Testen würde ich dann das Ganze, indem ich 
TC_RC so weit hochdrehe, dass die LED langsamer blinkt...

Der Code sieht momentan so aus:
1
AT91PS_TCB pTCB = AT91C_BASE_TCB;
2
AT91PS_TC pTC = AT91C_BASE_TC0;
3
4
void TimerSetup(void) 
5
{
6
  pTCB->TCB_BCR = 0;    // SYNC trigger not used
7
  pTCB->TCB_BMR = 0x15;   // external clocks not used
8
9
  pTC->TC_CCR = 0x5;      // enable the clock and start it
10
  pTC->TC_CMR = 0x4004;   // TCCLKS = 1 (TIMER_CLOCK5)
11
  pTC->TC_RC = 2346;      // 2346;
12
}
13
14
void main(void) 
15
{ 
16
  // init frequency
17
  InitFrec();
18
19
  // init leds / usart0
20
  InitPeriphery();
21
22
  TimerSetup();
23
24
25
  p_pPio->PIO_CODR = BIT17;  // LED 1 on
26
27
  // loop forever
28
  while(1)
29
  {
30
    p_pPio->PIO_CODR = BIT18;  // LED 2 on
31
    p_pPio->PIO_SODR = BIT17;  // LED 1 off
32
    wait(800000);
33
34
    p_pPio->PIO_SODR = BIT18;  // LED 2 off
35
    p_pPio->PIO_CODR = BIT17;  // LED 1 on
36
    wait(800000);
37
    
38
  // Hier sollte er eigentlich warten, bis der Takt wieder neu beginnt
39
  while(pTC->TC_SR != 0)
40
  {
41
  }
42
43
    p_pPio->PIO_CODR = BIT18;  // LED 2 on
44
    p_pPio->PIO_SODR = BIT17;  // LED 1 off
45
    wait(800000);
46
47
    p_pPio->PIO_SODR = BIT18;  // LED 2 off
48
    p_pPio->PIO_CODR = BIT17;  // LED 1 on
49
    wait(800000);
50
  }
51
52
  return (0);
53
}

von Peter P. (uncle-sam7)


Lesenswert?

Ok, dann muss ich wohl nachher zum Elektronikteilehändler meines 
Vertrauens und einen Oszillator usw. kaufen...

gute nacht

von Stephan W. (sir_wedeck)


Lesenswert?

Hi

also ich glaub dein TC_CMR Register ist falsch beschrieben.
du brauchst die Beschreibung mit Wave= 1 denke ich.
1
TC_CMR= AT91C_TC_WAVE |     // Wave aktive
2
 AT91C_TC_WAVESEL_UP_AUTO |   // <- bin ich mir nicht sicher
3
 AT91C_TC_CLKS_TIMER_DIV5_CLOCK |   // Takt
4
 AT91C_TC_ACPA_SET |   // bei wert A setzen
5
 AT91C_TC_ACPC_CLEAR;  // bei wert C löschen
6
7
TC_RA= 1173;  // 50 % von RC
8
TC_RC= 2346;  // <- das war deins

erst alle! Parameter setzen und danach den Counter starten!!!
Sonst gibs komische Effekte.

Atmel geht sogar noch weiter bei der Init
und beim Starten der TC: (aus der Vers. 1.5)
1
//------------------------------------------------------------------------------
2
/// Configures a Timer Counter to operate in the given mode. Timer is stopped
3
/// after configuration and must be restarted with TC_Start(). All the
4
/// interrupts of the timer are also disabled.
5
/// \param pTc  Pointer to an AT91S_TC instance.
6
/// \param mode  Operating mode (TC_CMR value).
7
//------------------------------------------------------------------------------
8
void TC_Configure(AT91S_TC *pTc, unsigned int mode)
9
{
10
    // Disable TC clock
11
    pTc->TC_CCR = AT91C_TC_CLKDIS;
12
    // Disable interrupts
13
    pTc->TC_IDR = 0xFFFFFFFF;
14
    // Clear status register  <--------------------- hier ein Dummy Read!!!
15
    pTc->TC_SR;
16
    // Set mode
17
    pTc->TC_CMR = mode;
18
}
19
//-------------------------------------------------------------------------
20
/// Enables the timer clock and performs a software reset to start the counting.
21
/// \param pTc  Pointer to an AT91S_TC instance.
22
//-------------------------------------------------------------------------
23
void TC_Start(AT91S_TC *pTc)
24
{
25
    pTc->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
26
}
27
//-------------------------------------------------------------------------
28
/// Disables the timer clock, stopping the counting.
29
/// \param pTc  Pointer to an AT91S_TC instance.
30
//-------------------------------------------------------------------------
31
void TC_Stop(AT91S_TC *pTc)
32
{
33
    pTc->TC_CCR = AT91C_TC_CLKDIS;
34
}

versuch mal das und gib Bescheid.

>// Hier sollte er eigentlich warten, bis der Takt wieder neu beginnt
dies würde ich anders schreiben:
1
// Hier sollte er eigentlich warten, bis der Takt wieder neu beginnt
2
  unsigned int tempTC_SR= pTC->TC_SR; // hier erst mal ein dummy read
3
  while(pTC->TC_SR != 0);   // und dann warten

bei deiner Lösung läuft er durch ist ja klar, da beim ersten mal was 
gesetzt war und wenn er wieder an diese Stelle kommt ist bestimmt irgend 
was gesetzt. also erst ein Dummy Read ausführen.

Stephan

von Peter P. (uncle-sam7)


Lesenswert?

Also ich hab das jetzt - so denke ich mal - korrekt eingebaut. 
Allerdings ergibt die Warteschleife zwischen den Blinkern einen 
Endlosloop...

Kann es sein, dass man erst mal wieder den Timerbereich im init-skript 
aktivieren muss? Wenn ja, wie sieht das ungefär aus?

Jetzt werd ich mich dann gleich mal um die Oszillator-alternative 
kümmern...
1
AT91PS_TCB pTCB = AT91C_BASE_TCB;
2
AT91PS_TC pTC = AT91C_BASE_TC0;
3
4
5
static void InitTimerCounter(void)   
6
{   
7
    pTC->TC_CCR = AT91C_TC_CLKDIS;
8
    // Disable interrupts
9
    pTC->TC_IDR = 0xFFFFFFFF;
10
    // Clear status register  <--------------------- hier ein Dummy Read!!!
11
    pTC->TC_SR;
12
    // Set mode
13
    pTC->TC_CMR = AT91C_TC_WAVE |     // Wave aktive
14
    AT91C_TC_WAVESEL_UP_AUTO |      // <- bin ich mir nicht sicher
15
    AT91C_TC_CLKS_TIMER_DIV5_CLOCK |   // Takt
16
    AT91C_TC_ACPA_SET |           // bei wert A setzen
17
    AT91C_TC_ACPC_CLEAR; 
18
      
19
  
20
  pTC->TC_RA = 1173;  // 50 % von RC
21
  pTC->TC_RC  = 2346;   
22
    pTC->TC_CCR = 5; //enable timer-counter and trig it          
23
24
    pTC->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
25
}
26
27
28
void main(void) 
29
{ 
30
  // init frequency
31
  InitFrec();
32
33
  // init leds / usart0
34
  InitPeriphery();
35
36
  InitTimerCounter();
37
38
    p_pPio->PIO_CODR = BIT17;  // LED 1 on
39
40
  // loop forever
41
  while(1)
42
  {
43
    p_pPio->PIO_CODR = BIT18;  // LED 2 on
44
    p_pPio->PIO_SODR = BIT17;  // LED 1 off
45
    wait(800000);
46
47
    p_pPio->PIO_SODR = BIT18;  // LED 2 off
48
    p_pPio->PIO_CODR = BIT17;  // LED 1 on
49
    wait(800000);
50
    
51
  // int status=AT91C_BASE_TC0->TC_SR;
52
  unsigned int tempTC_SR= pTC->TC_SR; // hier erst mal ein dummy read
53
    while(pTC->TC_SR == 0)
54
    {
55
    };   // und dann warten
56
 
57
58
59
    p_pPio->PIO_CODR = BIT18;  // LED 2 on
60
    p_pPio->PIO_SODR = BIT17;  // LED 1 off
61
    wait(800000);
62
63
    p_pPio->PIO_SODR = BIT18;  // LED 2 off
64
    p_pPio->PIO_CODR = BIT17;  // LED 1 on
65
    wait(800000);
66
  }
67
68
  return (0);
69
}

von Stephan W. (sir_wedeck)


Lesenswert?

Morgen,

ich hab hier was gefunden:

http://www.at91.com/forum/viewtopic.php/f,12/t,4203/

schau mal da, da sollte es laufen. ;-)
Hast du folgendes drin?
1
AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_TC0);      //enable clock
2
3
AT91C_BASE_PIOA->PIO_PDR = P_TIOA0;   //disable PIOA
4
AT91C_BASE_PIOA->PIO_BSR = P_TIOA0;   //select peripheral B
5
6
bzw:
7
// In order to select TIOA0, disable PB0 and select periph.A
8
AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, 0 , AT91C_PB0_TIOA0);

ich glaub das wars.

Stephan

von Peter P. (uncle-sam7)


Lesenswert?

Vielen Dank, werde ich später gleich mal testen. Hab den 1MHz Oszillator 
nicht bekommen. Der hatte erst ab 6MHz...

Hoffentlich funktioniert das mit dem Timer...

Bis später...

von Frank B. (foobar)


Lesenswert?

Peter Pippinger schrieb:
> "Schon wichtig"
>
> im Sinne von: da kann was kaputt gehen?
> oder eher
> im Sinne von: da kommen evtl. fehlerhafte Signale beim SID an?

Kaputtgehen kann eigentlich nichts, aber wenn die kurzzeitigen hohen 
Schaltströme, die bei CMOS-Bausteinen auftreten, nicht per 
Keramikkondensator abgefangen werden, dann kann die Spannung kurz 
einbrechen oder in extremen Fällen auch anfangen zu schwingen, je nach 
Verdrahtung, sodaß der SID unstabil arbeiten könnte, was auch das 
generierte Audiosignals beeinflussen könnte. Den Kondensator am besten 
direkt an den Versorgungspsannungs-Pins vom SID anlöten.

Da du übrigens keine Möglichkeit hast zu prüfen, ob die 1 MHz wirklich 
generiert werden, würde ich vorschlagen, einen Vorteiler zu wählen, 
sodaß es in den Audiobereich fällt, also bei ein paar kHz, falls 
möglich. Dann kannst du einfach einen hochohmigen Kopfhörer dranhängen 
(ein kleiner Piezo-Lautsprecher ist auch sehr gut geeignet) und hören, 
ob was rauskommt. Oder noch besser: per Soundkarte aufzeichnen. Gibt da 
gute Softwarelösungen für ein Soundkarten-Oszilloskop. Da kannst du dann 
die Frequenz exakt messen, wenn die niedriger als die Samplerate der 
Soundkarte ist. Dann die Frequenz raufsetzen.

Wenn alles nicht klappt: Ich habe hier auch noch einen 1 MHz 
Quarzoszillator mit 5 V Versorgungsspannung, den ich dir per 
Briefumschlag schicken könnte, sodaß du dir Versandkosten bei Reichelt 
o.ä. sparen würdest. Brauche ich sowieso nicht mehr, da die 
Microcontroller heutzutage ja meist per Quarz und nicht Quarzoszillator 
betrieben werden können und wenn man mal einen Quarzoszillator braucht 
(z.B. für FPGAs oder CPLDs), dann sowieso mit höherer Frequenz und 3,3 
V.

von Peter P. (uncle-sam7)


Lesenswert?

> Da du übrigens keine Möglichkeit hast zu prüfen, ob die 1 MHz wirklich
> generiert werden, würde ich vorschlagen, einen Vorteiler zu wählen,
> sodaß es in den Audiobereich fällt, also bei ein paar kHz, falls
> möglich. Dann kannst du einfach einen hochohmigen Kopfhörer dranhängen
> (ein kleiner Piezo-Lautsprecher ist auch sehr gut geeignet) und hören,
> ob was rauskommt.

ja, gute Ideen. Ich wollte irgendwas mit Schleifen & LED-Blinken machen 
um die Frequenz zu messen (naja, messen ist hier wohl optimistisch 
ausgedrückt :-)

> Wenn alles nicht klappt:

So ist es leider immer noch.
@Stephan W.: Hab Deine Beispiele in allen mir erdenklichen Versionen 
probiert, aber ich bekomm das nicht gebacken :-(

> Ich habe hier auch noch einen 1 MHz
> Quarzoszillator mit 5 V Versorgungsspannung, den ich dir per
> Briefumschlag schicken könnte, sodaß du dir Versandkosten bei Reichelt
> o.ä. sparen würdest. Brauche ich sowieso nicht mehr, da die
> Microcontroller heutzutage ja meist per Quarz und nicht Quarzoszillator
> betrieben werden können und wenn man mal einen Quarzoszillator braucht
> (z.B. für FPGAs oder CPLDs), dann sowieso mit höherer Frequenz und 3,3
> V.

Also das ist wirklich äußerst freundlich! Danke. Aber eine kleine Frage 
habe ich da noch. Muss der SID nicht am Clockinput nicht auch mit TTL 
betrieben werden?

siehe:
http://www.zimmers.net/anonftp/pub/cbm/schematics/computers/c128/manual/42.gif

Achso - dann passen 5V, oder:
http://www.elektronik-kompendium.de/sites/dig/0205171.htm

Also das mit dem Oszillator wäre wirklich ganz ganz nett, wenn Du mir 
den schicken könntest. Ich schick Dir meine Adresse via E-Mail. Vielen 
Dank schon mal.

von Frank B. (foobar)


Lesenswert?

3,3 V würden aber auch gehen, denn laut dem Datenblatt sind nur 
mindestens 2 V notwendig, auch für den Takteingang: 
http://sid.kubarth.com/files/ds_6581.pdf

Ich schicke dir aber vorsichtshalber gerne den Quarzoszillator. eMail 
habe ich noch keine bekommen, soll ich es an deine unter Xing 
eingetragene Adresse schicken?

von Stephan W. (sir_wedeck)


Lesenswert?

Morgen

könntest du den Code noch einmal mit den aktuellen Stand posten?
Das muss doch zu lösen sein?
Das ist eine Frage der Ehre!!!!

Stephan

PS: Wenn du anstatt den Pin zu wackeln do mal einen RC Compare INT 
schreibst, und dort was machst? (LED Schalten alle x mal oder so...)
So wüssten wir das der Timer läuft.

von Peter Pippinger (Gast)


Lesenswert?

Hallo Stephan,

ich würde die Variante mit dem Timer auch auf jeden Fall bevorzugen. Ich 
werde heut abend mal versuchen, das zu posten, was ich jetzt momentan im 
Quelltext stehen habe. Hab nur das Problem, dass ich halt auch viele 
verschiedene "Versionen" ausprobiere.

Stefan, hast Du auch das Board? Oder sowas ähnliches? Den Timer könnte 
man doch bestimmt auch so konfigurieren, dass die LED im sichtbaren 
Bereich blinkt. Von da weg zu arbeiten sollte kein Problem darstellen. 
Mist, das kann doch nicht so extrem schwierig sein. Man verwendet doch 
Timer in der Art auch, um einen Taster zu entprellen (glaube mal sowas 
gelesen zu haben). Wenn da jemand Erfahrung hat mit dem AT91SAM7S hat 
wäre es total nett, hier vielleicht einen luffähigen Schnipsel zu 
posten...

Prallel dazu hat mir der Frank (wirklich sehr freundlich :-) einen 1MHz 
Oszillator geschickt. Mit dem sollte das dann einfach machbar sein...

Viele Grüße,
Peter

von Stephan W. (sir_wedeck)


Angehängte Dateien:

Lesenswert?

Hi,
hab noch was gefunden, vielleicht hilft es.

Stephan

von Frank B. (foobar)


Lesenswert?

Wirklich sehr einfach für Hardwarekonfiguration usw. ist CodeWarrior mit 
dem "Processor Expert". Da kann man sich einfach per Eingabemasken 
eintragen und zusammenklicken, was man haben will. Die Eingebamasken 
nehmen einem alle Arbeit des Datenblatt-Lesens ab: Z.B. einfach 
eintragen, was für eine Frequenz man für einen periodischen Interrupt 
haben will und der Processor Expert sagt einem, mit welchem Fehler es 
machbar ist und generiert allen dazu nötigen Code:

http://www.frank-buss.de/MC9S08JS16L/

Ich bin allerdings eigentlich nicht ein Anhänger solcher Wizards, denn 
den Code kann man später meist nicht gut weiterentwickeln und wenn man 
die Register selber programmiert, dann hat man auch den Chip besser 
verstanden und kann besser die Fähigkeiten des Chips einschätzen und 
planen.

So habe ich z.B. mal die Register von einem Cypress PSoC Chip selber 
programmiert, statt den "Device Editor" zu nehmen, was interessant war, 
aber schon grenzwertig ist und wo ein grafischer Editor schon fast ein 
Muß ist, da es da sehr viele Bedingungen, Einschränkungen und 
Kombinationen zu beachten gibt:

http://www.frank-buss.de/rs232toi2c/

Ich weiß, ich habe merkwürdige Hobbies :-)

Der AT91SAM7 ist aber eher noch ein einfacher Chip in dieser Hinsicht. 
Nur leider sind die Atmel-Datenblätter manchmal ein wenig umständlich 
geschrieben, aber gibt auch da schlimmeres: Z.B. musste ich mal mit 
einem Datenblatt von einem Silicon Motion Chip arbeiten und obwohl der 
Chip recht gut war, war das Datenblatt sehr lückenhaft, da manchmal nur 
stand, wie ein Bit eines Registers hiess, aber nirgends zu finden war, 
was das Bit denn nun genau macht, sodaß man anhand des Namens und 
vielleicht ein wenig Beispielcode vom SDK erraten musste, wie es genau 
in eigenen Programmen zu verwenden ist (da der Support auch nicht sehr 
hilfreich war).

von Peter P. (uncle-sam7)


Lesenswert?

@frank: Der Oszillator ist leider noch nicht angekommen... vielleicht 
kommt er ja morgen :-)

@stephan: Hab heute mal ne Mail an den ATMEL Support geschrieben und 
nochmal unterstrichen wie wichtig mir die Sache ist. Prompt habe ich ne 
Antwort bekommen. Werde wahrscheinlich erst am WE dazukommen, das zu 
prüfen... Aber für die, die es interessiert:

Hello Peter,

You will find below a piece of code which initializes the PA21 I/O line 
to
output the main oscillator signal on PCK1:
AT91C_BASE_PIOA->PIO_PDR = 0x00200000; // Configure PA21 to be driven by
peripheral
AT91C_BASE_PIOA->PIO_OER = 0x00200000; // Configure PA21 as output
AT91C_BASE_PIOA->PIO_PPUDR = 0x00200000; // Disable pull-up on PA21
AT91C_BASE_PIOA->PIO_BSR = 0x00200000; // Assign PA21 to peripheral B
function

AT91C_BASE_PMC->PMC_SCER |= 0x00000200; // Enable PCK1
AT91C_BASE_PMC->PMC_PCKR[1] = 0x1; // Select Main Osc Output

Hope this help.

(anm. peter) ATMEL rocks!

von Peter P. (uncle-sam7)


Lesenswert?

also jetzt wirds ernst :-)

habe eben folgendes getestet. Ratet mal, was die gelbe LED gemacht 
hat...

..richtig: schwächer als sonst geleuchtet. Das bedeutet wohl, dass schon 
mal die Mainclock wie vom ATMEL-Support beschrieben ausgegeben wird :-)

Ist es eigentlich schlimm eine LED im MHz-Bereich zu schalten?

Ich bin so aufgeregt...


int main ( void )
{

  AT91C_BASE_PIOA->PIO_PDR = 1 << 17; // Configure PA17 to be driven by 
peripheral
  AT91C_BASE_PIOA->PIO_OER = 1 << 17; // Configure PA17 as output
  AT91C_BASE_PIOA->PIO_PPUDR = 1 << 17; // Disable pull-up on PA17
  AT91C_BASE_PIOA->PIO_BSR = 1 << 17; // Assign PA17 to peripheral B 
function

  AT91C_BASE_PMC->PMC_SCER |= 0x00000200; // Enable PCK1
  AT91C_BASE_PMC->PMC_PCKR[1] = 0x1; // Select Main Osc Output

  while(1){}
}

von Peter P. (uncle-sam7)


Lesenswert?

Ok, es ist in der Tat ein Signal. Habe nun auf der 2. LED den Status 
dargestellt (LED2 blinkt langsam -> hängt an PCK von LED1). Allerdings 
werde ich so wohl kaum "messen" können, wievie Hertz am PIN tatsächlich 
rauskommen, da der Code ja auch den ein oder anderen Takt benötigt... 
Hmm, hat jemand eine Idee, wie ich das machen könnte. Über einen 
Interrupt würde das bestimmt gehen, so dass ich x nur alle 10000 Takte 
auswerte und auf der LED ausgebe... Wollte eigentlich versuchen, dass 
die LED im Sekunden-Takt blinkt, und somit die Hertzzahl "messbar" ist. 
Kann vielleicht nochmal jemand die Zeilen um einen Teiler erweitern? 
Dann müsste man da auch gut "messen" können... Sozusagen die jetzige 
Config MIT einem Teiler (z.B. 64).
Danke schon jetzt dafür.
Peter
1
int main ( void )
2
{
3
  // init frequency
4
  // InitFrec();
5
6
  // init leds / usart0
7
  InitPeriphery();
8
9
  AT91C_BASE_PIOA->PIO_PDR = 1 << 17; // Configure PA17 to be driven by peripheral
10
  AT91C_BASE_PIOA->PIO_OER = 1 << 17; // Configure PA17 as output
11
  AT91C_BASE_PIOA->PIO_PPUDR = 1 << 17; // Disable pull-up on PA17
12
  AT91C_BASE_PIOA->PIO_BSR = 1 << 17; // Assign PA17 to peripheral B function
13
14
  AT91C_BASE_PMC->PMC_SCER |= 0x00000200; // Enable PCK1
15
  AT91C_BASE_PMC->PMC_PCKR[1] = 0x1; // Select Main Osc Output
16
  
17
  int x = 0;
18
  int blink = 0;
19
20
  while(1)
21
  {
22
    if(!((p_pPio->PIO_PDSR) & (1 << 17))) 
23
    {
24
      x++;
25
26
      if (x > 1800000)
27
      {
28
        x = 0;
29
        if (blink == 0)
30
        {
31
          p_pPio->PIO_CODR = BIT18;  // led2 on
32
          blink = 1;
33
        }
34
        else
35
        {
36
          p_pPio->PIO_SODR = BIT18;  // led2 off
37
          blink = 0;
38
        }
39
      }
40
    }
41
42
  }
43
}

von Stephan W. (sir_wedeck)


Lesenswert?

Morgen,

na da haste ja schnell eine Antwort bekommen. :-)
Aber ich dachte die mögliche Frequenz war dir zu groß?

im Reg. PMC_PCKR machst du die Einstellungen, welcher Clock und mit 
welchem Teiler gearbeitet werden soll.

momentan ist kein Teiler und der Mainclock gewählt. (18,432MHz)
mit einem Teiler von 64 und dem Mainclock wäre der Wert:

AT91C_BASE_PMC->PMC_PCKR[1] = 6 << 2 | 1;

siehe DB Kapitel 26.9.11

Stephan

von Peter (Gast)


Lesenswert?

Stephan W. schrieb:
> na da haste ja schnell eine Antwort bekommen. :-)
> Aber ich dachte die mögliche Frequenz war dir zu groß?

...ja, hab auch kräftig auf die Tränendrüse gedrückt ;-)

> im Reg. PMC_PCKR machst du die Einstellungen, welcher Clock und mit
> welchem Teiler gearbeitet werden soll.

...ich glaube, dass habe ich jetzt sogar endlich verstanden. Habe 
gestern auch ´ne Version mit
AT91C_BASE_PMC->PMC_PCKR[1] = 0x1 + 8 + 16;
gemacht, was ja doch eigentlich genau das selbe ist, oder?
> AT91C_BASE_PMC->PMC_PCKR[1] = 6 << 2 | 1;

Die LED hat dann viel heller geleuchtet. Aber sollten nicht die hell und 
dunkel Phasen in der Summe genau wie bei 18 MHz sein? Also hätte ich 
eher erwartet, dass die LED von der helligkeit her gleich bleibt...

Was ich jetzt nicht ganz verstehe: Der Takt am Pin läuft doch nun 
unabhänig von der Programmierung in der while(1) Schleife?

Somit müsste ich doch mit einer entsprechend niedrigen Frequenz auf dem 
PIN in der Lage sein, JEDEN Statuswechsel mitzubekommen, oder? Ich hatte 
das Gefühl, dass sich nichts ändert...

Also nehmen wir mal an, die Frequenz am PIN wäre 1000 Hz, dann müsste 
doch, wenn ich x bis 1000 zählen lasse die LED im Sekundentakt blinken, 
oder?

MfG
Peter

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,
ja du kannst den SLOW-Clock als Quelle wählen, müssten 32 KHz sein. 
(Teiler auf 32)
Wenn du dann bis 1000 zählst sollte es ungefähr 1 Sekunde ergeben.

Der Takt selber läuft ohne MC Unterstützung, im Grunde musst du dir das 
so vorstellen, das eine Leitung von deinem Quarz über einen Teilen nach 
außen geführt wird. (vereinfacht gesprochen, Schaltbild gibt es im 
Datenblatt)

Stephan

von Peter (Gast)


Lesenswert?

...könntest Du mir vielleicht noch ganz kurz sagen, wo ich die 
Slow-clock wähle (nur für den Fall, dass ich das heute Abend nicht finde 
:-)

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,
steht auch im Register: PMC_PCKR !

Stephan

von Peter P. (uncle-sam7)


Lesenswert?

OK, danke. Aber eine Frage habe ich noch: Betrifft die Slow-Clock in 
diesem Fall dann nur diesen besagten Pin, oder wird dadurch auch der 
AT91SAM7S256-Takt langsamer? Weil wenn dem so wäre, dann würde mir das 
in diesem Fall auch nicht ein sicheres abfragen ALLER High-Low 
Statuswechsel garantieren...

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Frank,

meine Frau hat mir eben Deinen Brief mit dem Oszillator und den 
Kondensatoren gegeben :-)

Vielen vielen Dank!

Ich denke, dass mit all dem Wissen und em Equipment nun nichts mehr im 
Wege stehen sollte, dem SID spätestens am WE ein paar Töne zu entlocken 
:-)

Danke.

Gruß,
Peter

von Stephan W. (sir_wedeck)


Lesenswert?

Hi

der Slow-Clock ist immer da, der startet den MC so zusagen.
Diese Einstellung bezieht sich nur auf den Ausgangspin für diese 
Funktion.
Dein MC bleibt auf der alten Geschwindigkeit.

Du kannst ja auch allen 3 Ausgangspins eine unterschiedliche Frequenz 
geben.
1. Pin Slow-Clock
2. Pin Main-Clock
3. PLL Clock ( obwohl ich bezweifele das der MC die schnellen Frequenzen 
kann)

Stephan

von Peter P. (uncle-sam7)


Lesenswert?

So, jetzt glaube ich wirklich, dass ich langsam begreife, wie das Zeug 
hier funktioniert :-)

was ich gestern vergessen hatte (da bin ich tatsächlich selber drauf 
gekommen): Ich muss natürlich innerhalb des High auch so lange warten, 
bis wieder low anliegt, sonst stimmt ja der Zähler nicht. Was soll ich 
sagen? die LED switched nun 1/s. Cool.
1
  ...
2
  AT91C_BASE_PIOA->PIO_PDR = 1 << 17; // Configure PA17 to be driven by peripheral
3
  AT91C_BASE_PIOA->PIO_OER = 1 << 17; // Configure PA17 as output
4
  AT91C_BASE_PIOA->PIO_PPUDR = 1 << 17; // Disable pull-up on PA17
5
  AT91C_BASE_PIOA->PIO_BSR = 1 << 17; // Assign PA17 to peripheral B function
6
7
  AT91C_BASE_PMC->PMC_SCER |= 0x00000200; // Enable PCK1
8
  AT91C_BASE_PMC->PMC_PCKR[1] = 0x0 + 4 + 16 ; // Select Main Osc Output + Slow Clock
9
  
10
  int x = 0;
11
  int blink = 0;
12
13
  while(1)
14
  {
15
    if(!((p_pPio->PIO_PDSR) & (1 << 17))) 
16
    {
17
      x++;
18
      // wait until the next status change
19
      while(!((p_pPio->PIO_PDSR) & (1 << 17)))
20
      {
21
      }
22
23
      if (x > 1000)
24
      {
25
        x = 0;
26
        if (blink == 0)
27
        {
28
          p_pPio->PIO_CODR = BIT18;  // led2 on
29
          blink = 1;
30
        }
31
        else
32
        {
33
          p_pPio->PIO_SODR = BIT18;  // led2 off
34
          blink = 0;
35
        }
36
      }
37
    }
38
  }

von Frank B. (foobar)


Lesenswert?

Man sollte den Code dann noch ein wenig aufräumen. Hier ein paar Tipps:

- Code immer so schreiben, daß man keinen Kommentar braucht
- das beinhaltet z.B.: keine magischen Zahlen verwenden
- kurze Funktionen verwenden
- direkte Hardwarezugriffe von der Programmlogik trennen

Könnte dann so aussehen (ungetestet)
1
#define CLOCK_BIT (1 << 17)
2
#define LED_BIT (1 << 18)
3
4
void initClock(void)
5
{
6
  AT91C_BASE_PIOA->PIO_PDR = CLOCK_BIT; // Configure PA17 to be driven by peripheral
7
  AT91C_BASE_PIOA->PIO_OER = CLOCK_BIT; // Configure PA17 as output
8
  AT91C_BASE_PIOA->PIO_PPUDR = CLOCK_BIT; // Disable pull-up on PA17
9
  AT91C_BASE_PIOA->PIO_BSR = CLOCK_BIT; // Assign PA17 to peripheral B function
10
  
11
  AT91C_BASE_PMC->PMC_SCER |= 0x00000200; // Enable PCK1
12
  AT91C_BASE_PMC->PMC_PCKR[1] = 0x0 + 4 + 16 ; // Select Main Osc Output + Slow Clock
13
}
14
15
inline void setLed2(int on)
16
{
17
  if (on) {
18
    p_pPio->PIO_CODR = LED_BIT;
19
  } else {
20
    p_pPio->PIO_SODR = LED_BIT;
21
  }
22
}
23
24
inline int isClockBitSet(void)
25
{
26
  return (p_pPio->PIO_PDSR & CLOCK_BIT) == CLOCK_BIT;
27
}
28
29
inline void waitForFallingEdgeOnClockPin(void)
30
{
31
  while (!isClockBitSet()) {}
32
  while (isClockBitSet()) {}
33
}
34
35
void main(void)
36
{
37
  int x = 0;
38
  int blink = 0;
39
  initClock();
40
  while (1) {
41
    waitForFallingEdgeOnClockPin();
42
    if (x++ == 1000) {
43
      setLed2(blink);
44
      blink = !blink;
45
      x = 0;
46
    }
47
  }
48
}

Die "magischen" Zahlen 0x00000200 usw. kann man bestimmt auch noch mit 
den entsprecheneden defines aus den include-Dateien der Atmel-Libraries 
ersetzen, da wo auch AT91C_BASE_PIOA usw. herkommt.

Manchmal muß man aber Kompromisse machen, wenn z.B. der Takt-Pin sehr 
schnell schaltet und da kann dann auch sogar eine kurze Assemlber-Inline 
Routine notwendig werden. Sowas sieht man dann aber nur noch per 
Oszilloskop, denn auch wenn man die Assembler-Ausgabe des C-Compilers 
analysieren würde, würde man Effekte wie Prozessor-Cache usw. nicht so 
leicht manuell berücksichtigen können.

Ich denke aber immer noch, daß es für den SID egal ist, mit welcher 
Flanke sich die Signale exakt ändern, sodaß du nur entsprechend 
Chipselect usw. zu setzen brauchst und dann ein wenig warten, wie in dem 
anderen Thread zum SID beschrieben.

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Frank,

vielen Dank für die Tips. Man möchte es vielleicht nicht glauben, aber 
ich verdiene meine Brötchen auch mit dem Programmieren :-) Bin 
eigentlich immer bemüht, die Dinge sio zu machen, wie Du sie oben 
beschrieben hast. Der Code ist (noch) mit der heißen Nadel und ganz 
wenig Zeit gestrickt, da ich einfach noch viel zu viel umbauen, testen 
und verstehen musste. Also die Chancen stehen gut, dass der Code am Ende 
besser aussieht :-)

> Ich denke aber immer noch, daß es für den SID egal ist, mit welcher
> Flanke sich die Signale exakt ändern, sodaß du nur entsprechend
> Chipselect usw. zu setzen brauchst und dann ein wenig warten, wie in dem
> anderen Thread zum SID beschrieben.

Im Prinzip gebe ich Dir da recht. Man müsste aber dann - so denke ich - 
mindestens 2 Takte warten, da der "Einstiegspunkt" ja nicht feststeht. 
Das wiederum könnte ja durchaus dazu führen, dass ein Register 2x 
hintereinander gesetzt wird. Ich weiß nicht, der Gedanke daran gefällt 
mir nicht so gut. Es tut ja nicht weh, diesen Wechsel abzuwarten...

von Frank B. (foobar)


Lesenswert?

Klar, du kannst versuchen, den Wechsel abzuwarten. Bei 1 MHz müsstest du 
dann aber berücksichtigen, wieviel Takte der Code braucht, um den Test 
durchzuführen und den Pin umzuschalten. Das kann schwierig werden, falls 
man Prozessor Cache, Pipelining und ggf. zusätzlich Latenz beim 
GPIO-Umschalten berücksichtigen muß, denn manche CPUs schalten die GPIOs 
nicht mit dem Prozessor-Takt um bzw. lesen den neuen Status ein, sondern 
mit einem langsameren IO-Takt (war glaube ich bei den AT91-Chips auch 
so). Wenn du also von der Programmlogik her meinst, einen Pegelwechsel 
am Pin erkannt zu haben, dann liegt der in Wirklichkeit vielleicht schon 
viele Prozessortakte in der Vergangenheit. Im schlimmsten Fall führt das 
dann dazu, daß du das Timing genau falsch machst (also z.B. 180° 
phasenverschoben) und den SID nicht angesprochen bekommst, obwohl du es 
nur gut meinst :-)

von Peter (Gast)


Lesenswert?

Hallo Frank,

...deswegen war es mir ja wichtig, das nicht über einen Interrupt zu 
machen, so dass genügend Rechenpower fürs Warten zur Verfügung steht. 
Wenn der ARM mit 50 MHz läuft, und der PIN mit 1 MHz, dann sollte es auf 
jeden Fall möglich sein, einen Status aus dem Register zu lesen und 
entscheiden, ob das wiederholt werden soll (wie in meiner Schleife). Ich 
würde mal so aus dem Bauch raus vermuten, dass der ARM dafür 4 Takte 
braucht. Die genaue Blink-Frequenz von 1/sek zeigt mir doch eigentlich 
auch an, dass das so funktioniert, oder?

Das mit der Latzenz und dem Caching finde ich allerdings in diesem Fall 
schon sehr komisch, wenn das wirklich so ist. Ich muss doch genau 
wissen, was passiert. Das wäre doch - salopp gesagt - so wie wenn ich 
den Feuerknopf am Joystick drücke und ein Spiel dann erst viel später 
von dem Ereignis mitbekommen würde? Also das ist mal überspitz 
dargestellt, aber ich denke, wenn man die Timings der beiden Situationen 
hochskalieren würde, dann würde sowas ähnliches rauskommen, oder?

Naja, wie dem auch sei, ich hoffe am WE wissen wir mehr. BTW.: hast Du 
zufällig eine Ahnung, ob ich zum Testen an den Audio-Out einen 
Walkmankopfhörer anschließen kann? Ich hab irgendwo - glaube ich - 
gelesen, dass da so 3V Spannung am Auido Out sind? Wenn nein, kann ich 
dann einen Wiederstand hin, oder gar ein Trimpoti zum Regeln der 
Lautstärke?

Gruß
Peter

von Frank B. (foobar)


Lesenswert?

Wenn es langsamer ist, dann wird die Blinkfrequenz stimmen, also wenn du 
bis 1000 zählst, der Ausgang auch auf 1000 Hz ist und du eine 
Blinkfrequenz von 0,5 Hz messen kannst, dann stimmt das für diesen Fall. 
Wenn du dann anhand der Register meinst, daß du eine Frequenz an dem Pin 
von 1 MHz hast und dann bis 1 Millionen zählst und immer noch 0,5 Hz 
misst, dann funktioniert es. Kannst ja zum Spaß dann auch mal den Quarz 
an einem GPIO dranhängen (die IOs sind ja 5V tolerant) und messen, da 
sollte die LED dann auch mit 0,5 Hz blinken, falls es nicht zu sehr 
prellt, sonst die Glitch-Filter des AT91 einschalten.

Generell ist es aber schon so, daß du nicht sofort mitbekommst, wann ein 
Pegel extern wechselt. Für einen Feuerknopf am Joystick wird aber die 
Mikrosekunden Verzögerung nicht allzuviel ausmachen :-)

Ich weiß, Datenblatt lesen ist nicht dein Fall, aber in dem Datenblatt 
hier:

http://www.atmel.com/dyn/resources/prod_documents/doc6175.pdf

findest du auf Seite 245 das Output Line Timing. Da siehst du mehrere 
Takte Verzögerung beim Schreiben auf einen Port. "APB Access" bedeutet 
übrigens, daß das der Zeitpunkt ist, bei dem der APB-Bus frei ist, zum 
PIO Daten zu schaufeln. Auf Seite 4 findest du da eine Übersicht zu. APB 
heisst übrigens "Advanced Peripheral Bus" ausgeschrieben und ist Teil 
der AMBA Spezifikation, wie du hier nachlesen kannst:

http://en.wikipedia.org/wiki/AMBA_specification

Das ist aber schon recht tiefgehend. Für dich wichtig ist, daß an den 
APB-Bus viele Einheiten angebunden sind und wenn der Chip gerade damit 
beschäftigt ist, das Flash anzusprechen, z.B. um deinen Code zu laden, 
dann kann der nicht auf die GPIOs zugreifen und muß da erstmal warten.

Und schließlich kommt noch die Latenz durch die Pipeline hinzu. Laut dem 
Artikel hier:

http://de.wikipedia.org/wiki/ARM-Architektur

hat der ARM7-Core, der in dem AT91SAM7S eingesetzt wird, eine 
dreistufige Pipeline. Also alles in allem würde ich mal von dem Befehl 
zum Lesen des Pins rückwärts in der Zeit mit 5-8 Takten rechnen. Diesen 
Wert bekommst du dann. Wenn dann noch ein paar mehr Befehle dahinter zum 
Auswerten kommen, ist man schnell bei 10 Takten. Ginge vielleicht noch, 
aber du musst dasselbe ja auch wieder für den Ausgang rechnen. Daher 
meine Vermutung, daß du eine kräftige Phasenverschiebung reinbekommst, 
die man praktisch nur per Oszilloskop messen kann. Wäre aber möglich, 
daß 1 MHz noch machbar ist.

Ist alles nicht so einfach, wie bei kleinen 8-bittigen Microcontrollern.

Und schon wieder ein Datenblatt :-) siehe zum Anschluss am Audio Out 
Seite 8:

http://sid.kubarth.com/files/ds_6581.pdf

Die Ausgangsspannung hängt also davon ab, wieviel du an VDC reingibst. 
5V scheinen auch zu gehen, was die Beschaltung einfacher macht.

Als Last ist da 1 kOhm angegeben. Ich würde das besser auch nicht 
stärker belasten, also eher kein Walkman Kopfhöhrer (es sei denn mit 1 
kOhm Vorwiderstand, was dann recht leise klingen wird), sondern besser 
Soundkarten- oder HiFi-Anlageneingang.

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Frank,

Wollte Dir noch sagen, dass das Beispiel von Dir, wie der Code aussehen 
könnte echt elegant ist. Gefällt mir.

Ich habe nun mal die Funktion geschrieben, um die Datenleitung und 
Adressleitung zu setzen. Was mir dabei gleich noch aufgefallen ist:

Bei meinem Board 
http://www.olimex.com/dev/pdf/ARM/ATMEL/SAM7-P256-SCH-REV-F.pdf sind 
manche I/O-Pins, die rausgeführt werden bereits belegt. Bringt das 
Probleme in der Zukunft? Gerade wenn ich mir z.B. den SDCard-Slot 
ansehe. SID würde beim Zugriff ruhen. Kann dem SID was passieren, wenn 
ich auf die SDCard zugreife? Und anders herum kann der SDCard was 
passieren, wenn ich auf den SID zugreife? Gerade auch vor dem 
Hintergrund 5V TTL (SID lesen).

Z.Zt würde ich die Leitungen so in der Art benützen
5 oder 6 Leitungen warens glaube ich für den HD44780 (4Bit)
RS232 wäre auch nicht schlecht, da ich da ganz gut "poorman debugger" 
spielen kann...

(PAxx rausgeführt / paxx nicht):

PA01 - SID A1
PA02 - SID A2
PA03 - SID A3
PA04 - SID A4
PA05 - SID Reset
PA06 - SID TAKT
PA07 - SID R/W
PA08 - SID CS
PA09 - SID D0
PA10 - SID D1
PA11 - SID D2  SD Card
PA12 - SID D3  SD Card
PA13 - SID D4  SD Card
PA14 - SID D5  SD Card
PA15 - SID D6
PA16 - SID D7
pa17 -    LED2
pa18 -     LED1
pa19 -     Button1
pa20 -    Button2
PA23 -
PA26 -
PA27 -
PA28 -
PA29 -
PA30 -
PA31 -

Hoffe, dass ich morgen abend/nacht schon mal das erste Lied 
rausbekomme...

von Frank B. (foobar)


Lesenswert?

Wie es aussieht hat das Olimex-Board die SD-Card direkt angeschlossen, 
ohne zusätzlichen Schutzchip. Das ist ok, wenn du die SD-Card immer nur 
dann wechselst, wenn der Strom aus ist.

Den SID würde die 3,3 V von der SD-Card nicht stören, falls das immer 
per Chipselect sauber getrennt ist. Hängt dann von der SD-Card ab, ob 
die die 5 V mag, wovon ich jetzt erstmal nicht ausgehen würde (also SID 
oder SD-Card fängt an zu rauchen :-) . Wenn du planst, da eine 
einzustecken, dann würde ich andere Pins emfpehlen. Die ARM-Architektur 
ist ja recht effizient, falls der Compiler gut ist, was das 
Auseinandernehmen von Wörtern und das Verschieben von Bits betrifft, 
sodaß die nicht kontinuierlich hintereinander liegen müssen. Vorteil 
wäre auch, daß man per PDC im Hintergrund, ohne Prozessorlast, auf den 
SPI-Bus für die SD-Card zugreifen kann und parallel dazu dann den SID 
ansteuern kann, falls du mal parallel zum Playback Lieder nachladen 
willst.

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Frank,

das habe ich mir schon fast gedacht, dass ich da aufpassen muss... Das 
Auseinandernehmen der Bits würde dann mit schieben und logischen 
Operatoren machen, oder gibts da was ganz spezielles?

Momentan würde ich grob gesagt auf ein Bit Testen und das dann an die 
richtige Stelle "übersetzen"...

Mal noch was ganz anderes: Beim Setzen der High-Low Zustände auf den 
Pins:

es gibt doch 2 Möglichkeiten:
CODR + SODR:
    da lösche ich doch erst mal die Bits mit CODR, die ich nicht mag
    und mit SODR setze ich die, die ich mag. Aber das bedeutet doch,
    dass zwischen CODR und SODR ein falsches "Ausgangsbild" entsteht,
    oder? Kann man dem AT91SAM7S irgendwie sagen, dass er den neuen
    Zustand per Befehl übernehmen soll?

Dann gibts ja glaube ich auch die Möglichkeit High und Low über ein 
einziges Register zu beschreiben. Ich sag mal salopp: wo 0 und 1 als Low 
und High interpretiert wird. Das habe ich auch schon mal gemacht. Aber 
dazu müsste ich doch erstmal den "Gesamtzustand" holen, den dann 
anpassen und dann zurückschreiben (über dieses Register)?

Welchen Weg würdest Du als sauber und schnell einschätzen?

Gruß
Peter

von Frank B. (foobar)


Lesenswert?

Ich weiß, Datenblätter lesen sich nicht unbedingt wie ein spannender 
Roman :-) aber schau dir mal 27.4.5 hier an:

http://www.atmel.com/dyn/resources/prod_documents/doc6175.pdf

von Peter P. (uncle-sam7)


Lesenswert?

Hallo NG,

habe mir heute einen 16MHz Quarz gekauft und anstatt des 18,432MHz auf 
das Board gebaut. Leider sagt Windows dann schon, dass es die Hardware 
nicht kennt, oder kein passender Treiber installiert ist.

Kann ich den Quarz nicht einfach austauschen? Mit dem anderen 
funktionierts ohne Probleme...

MfG
Peter

von Frank B. (foobar)


Lesenswert?

Nein, den Quarz kannst du nicht einfach so tauschen, da die Frequenz für 
USB gebraucht wird, vermute ich mal. Genaueres sagt aber das Datenblatt 
und die Schaltung.

von Peter (Gast)


Lesenswert?

Hallo zusammen,

jetzt habe ich mal alles fertig verkabelt. Wo ich jetzt allerdings noch 
Bauchweh habe (aus dem Datenblatt):

5V-tolerant means that the I/O lines can drive voltage level according 
to VDDIO, but can be driven with a voltage of up to 5.5V. However, 
driving an I/O line with a voltage over VDDIO while the programmable 
pull-up resistor is enabled will create a current path through the 
pull-up resis156175K–ATARM–30-Aug-10 AT91SAM7S Series Preliminarytor 
from the I/O line to VDDIO. Care should be taken, in particular at 
reset, as all the I/O lines default to input with the pull-up resistor 
enabled at reset.

Der SID ist ja TTL 5V.

Wenn ich die Pins Direkt anschließe, muss ich dann "nur" darauf achten, 
dass die Pullups im AT91SAM7S deaktiviert sind? Dann ist alles OK, oder? 
Wenn die Pullups aktiv sind, ist dann auf VDDIO 5V ggf. vom SID? Oder 
was passiert dann? Da geht dann schon was kaputt, oder?

Ansonsten - die Bypasses - sind nun alle dran, nach dem Anschalten 
raucht nix. Code für Testton für 6510 habe ich mir aufm 64er Emulator 
zusammengebastelt. Also sollte es losgehen, sobald ihr grünes Licht 
wegen der internen Pullups im AT91SAM7 gebt...

Danke für jeden Hinweis...

Gruß,
Peter

von Frank B. (foobar)


Lesenswert?

Ich denke nicht, daß es da ein Problem geben wird. Laut Datenblatt 
fliessen bei eingeschalteten Pullups maximal 600 uA nach Masse. Das 
einzige was dabei dann dem Atmel gefährlich werden könnte ist, wenn es 
sich summiert, sodaß VDDIO dann von der Spannung zu hoch wird, weil 
normale Spannungsregler meist nur Last ausregeln können, aber nicht 
Spannung wegregeln können, die an der Ausgangsseite angelegt wird. Ich 
denke mal, du könntest das Problem recht leicht umgehen, indem du die 
maximale Last, also bei 8 Anschlüssen vom SID Richtung Atmel 48 mA, als 
Last an VDDIO dranhängst, wenn du ganz sicher gehen willst.

Wenn du allerdings den SID Chipselect per Pullup angeschlossen hast, 
dann kommt nach dem Reset der SID gar nicht mit aktiven Ausgängen, sodaß 
du also vom Programm her alle Zeit der Welt hast, erstmal die Pullups 
auszuschalten, sodaß du das dann auch nicht mehr brauchst. Aber du 
kannst ja sicherheitshalber nochmal für deinen konkreten Fall beim Atmel 
Support anfragen, die helfen meist gut weiter. Und ein Multimeter an 
VDDIO dranhängen und sobald es zuviel Spannung zeigt, schnell den 
Stecker ziehen :-)

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Frank,

bin mir zwar nicht sicher, ob ich im letzten Post ein wenig Sarkasmus 
gelesen habe, aber trotzdem Danke. Ich denke jetzt dauerts nicht mehr 
lang, bis der SID kaputt ist, oder alles funktioniert.

Habe eben die Adress und Datenleitungen gefüttert. Denkst Du, dass das 
hier ok ist, oder gibt es einen eleganteren Weg (wenn man Felxibilität 
mit der Pinbelegung haben möchte):
1
#define LED1      BIT17
2
#define LED2      BIT18
3
#define BUTTON1   BIT19
4
#define BUTTON2   BIT20
5
6
#define SID_A0    BIT0
7
#define SID_A1    BIT1
8
#define SID_A2    BIT2
9
#define SID_A3    BIT3
10
#define SID_A4    BIT4
11
#define SID_RES   BIT5
12
#define SID_CLOCK BIT6
13
#define SID_RW    BIT7
14
#define SID_CS    BIT8
15
16
#define SID_D0    BIT16
17
#define SID_D1    BIT23
18
#define SID_D2    BIT26
19
#define SID_D3    BIT27
20
#define SID_D4    BIT28
21
#define SID_D5    BIT29
22
#define SID_D6    BIT30
23
#define SID_D7    BIT31
24
25
p_pPio->PIO_ODSR = 
26
    (((adresse & 1)/1)    * SID_A0) +
27
    (((adresse & 2)/2)    * SID_A1) +
28
    (((adresse & 4)/4)    * SID_A2) +
29
    (((adresse & 8)/8)    * SID_A3) +
30
    (((adresse & 16)/16)  * SID_A4) +
31
32
    (((wert & 1)/1)       * SID_D0) +
33
    (((wert & 2)/2)       * SID_D1) +
34
    (((wert & 4)/4)       * SID_D2) +
35
    (((wert & 8)/8)       * SID_D3) +
36
    (((wert & 16)/16)     * SID_D4) +
37
    (((wert & 32)/32)     * SID_D5) +
38
    (((wert & 64)/64)     * SID_D6) +
39
    (((wert & 128)/128)   * SID_D7);

Gruß und gute Nacht,
Peter

von Peter P. (uncle-sam7)


Lesenswert?

Hallo,

jetzt habe ich mal alles angeschlossen und den "Code" für einen Ton an 
den SID geschickt. Das Einzige was passiert, ist dass er kurz knackst 
und das wars dann... Keine Ahnung, wie ich jetzt weiter vorgehen soll. 
Hab natürlich schon ein paar Sachen Probiert.

Die Leitungen habe ich im "Slowmotion"-Modus mit LED geprüft. Das hat 
eigentlich alles super ausgesehen von der Reihenfolge und so... Timings 
habe ich auch verschiedene probiert. Alles ohne Erfolg...

hier mal das Chaos bis jetzt:
1
#include "Board.h" 
2
#include "AT91SAM7S256.h"
3
4
#define LED1    BIT17
5
#define LED2    BIT18
6
#define BUTTON1    BIT19
7
#define BUTTON2    BIT20
8
9
#define SID_A0    BIT0
10
#define SID_A1    BIT1
11
#define SID_A2    BIT2
12
#define SID_A3    BIT3
13
#define SID_A4    BIT4
14
#define SID_RES    BIT5
15
#define SID_CLOCK  BIT6
16
#define SID_RW    BIT7
17
#define SID_CS    BIT8
18
19
#define SID_D0    BIT16
20
#define SID_D1    BIT23
21
#define SID_D2    BIT26
22
#define SID_D3    BIT27
23
#define SID_D4    BIT28
24
#define SID_D5    BIT29
25
#define SID_D6    BIT30
26
#define SID_D7    BIT31
27
28
#include "system.h"
29
#include "system.c"
30
31
// Pullups für die Datenleitungen und die Taktleitung deaktivieren
32
void pull_ups_fuer_sid_ausschalten(void)
33
{
34
  AT91C_BASE_PIOA->PIO_PPUDR = 
35
    SID_D0 +
36
    SID_D1 +
37
    SID_D2 +
38
    SID_D3 +
39
    SID_D4 +
40
    SID_D5 +
41
    SID_D6 +
42
    SID_D7 +
43
    SID_CLOCK;
44
}
45
46
void poke(unsigned short adresse, char wert)
47
{
48
49
  // Bits maskieren, die gesetzt werden können
50
  p_pPio->PIO_OWER =
51
    SID_A0 +
52
    SID_A1 +
53
    SID_A2 +
54
    SID_A3 +
55
    SID_A4 +
56
    SID_D0 +
57
    SID_D1 +
58
    SID_D2 +
59
    SID_D3 +
60
    SID_D4 +
61
    SID_D5 +
62
    SID_D6 +
63
    SID_D7;
64
65
  // Datenleitung
66
  p_pPio->PIO_ODSR = 
67
    (((adresse & 1)/1)    * SID_A0) +
68
    (((adresse & 2)/2)    * SID_A1) +
69
    (((adresse & 4)/4)    * SID_A2) +
70
    (((adresse & 8)/8)    * SID_A3) +
71
    (((adresse & 16)/16)  * SID_A4) +
72
73
    (((wert & 1)/1)      * SID_D0) +
74
    (((wert & 2)/2)      * SID_D1) +
75
    (((wert & 4)/4)      * SID_D2) +
76
    (((wert & 8)/8)      * SID_D3) +
77
    (((wert & 16)/16)    * SID_D4) +
78
    (((wert & 32)/32)    * SID_D5) +
79
    (((wert & 64)/64)    * SID_D6) +
80
    (((wert & 128)/128)    * SID_D7);
81
82
    p_pPio->PIO_CODR = SID_CS;
83
    wait_sid_cycles(2);      
84
    p_pPio->PIO_SODR = SID_CS;
85
}
86
87
void wait_sid_cycles(int cycles)
88
{
89
  while (cycles != 0)
90
  {
91
    while(!((p_pPio->PIO_PDSR) & SID_CLOCK))
92
    {
93
    }
94
    while(((p_pPio->PIO_PDSR) & SID_CLOCK))
95
    {
96
    }
97
    cycles--;
98
  }
99
}
100
101
void sid_reset(void)
102
{
103
  p_pPio->PIO_CODR = SID_RES;
104
  wait_sid_cycles(20);      // must wait at least 10 SID cycles
105
  p_pPio->PIO_SODR = SID_RES;
106
107
  p_pPio->PIO_CODR = SID_RW;    // our SID is write only
108
  p_pPio->PIO_SODR = SID_CS;    // CS High, Low on read / write
109
}
110
111
int main(void)
112
{
113
  // init leds / usart0
114
  InitPeriphery();
115
  pull_ups_fuer_sid_ausschalten();
116
117
  p_pPio->PIO_CODR = LED1;
118
119
  AT91C_BASE_PIOA->PIO_PDR  = SID_CLOCK;  // Configure SID_CLOCK to be driven by peripheral
120
  AT91C_BASE_PIOA->PIO_OER  = SID_CLOCK;  // Configure SID_CLOCK as output
121
  AT91C_BASE_PIOA->PIO_PPUDR  = SID_CLOCK;  // Disable pull-up on SID_CLOCK
122
  AT91C_BASE_PIOA->PIO_BSR  = SID_CLOCK;  // Assign SID_CLOCK to peripheral B function
123
124
  AT91C_BASE_PMC->PMC_SCER |= 0x00000100;    // Enable PCK1
125
  AT91C_BASE_PMC->PMC_PCKR[0] = 1 + 16 ;    // Select Main Osc Output + Slow Clock
126
127
  // SID Reset erst möglich, nachdem Takt steht.
128
  sid_reset();
129
130
  while(1)
131
  {
132
    poke(0xD418, 15);
133
    p_pPio->PIO_CODR = LED1;
134
    wait_sid_cycles(100000);
135
    poke(0xD400, 196);
136
    p_pPio->PIO_SODR = LED1;
137
    wait_sid_cycles(100000);
138
    poke(0xD401, 9);
139
    p_pPio->PIO_CODR = LED1;
140
    wait_sid_cycles(100000);
141
    poke(0xD405, 94);
142
    p_pPio->PIO_SODR = LED1;
143
    wait_sid_cycles(100000);
144
    poke(0xD406, 71);
145
    p_pPio->PIO_CODR = LED1;
146
    wait_sid_cycles(100000);
147
    poke(0xD404, 33);
148
    p_pPio->PIO_SODR = LED1;
149
    wait_sid_cycles(100000);
150
151
    while(1)
152
    {
153
    }
154
  }
155
}

von Frank B. (foobar)


Lesenswert?

Sieht eigentlich gut aus der Code, nur daß ich "*" und "/" durch 
Shift-Operatoren (>> und <<) ersetzen würde (Operator-Präzedenz dabei 
beachten).

In so einem Fall würde ich mit einem Scope nachmessen, ob alles auch so 
ist, wie es sein soll, also liegen tatsächlich 1 MHz an? Kommen alle 
Signale wie erwartet nach dem Chipselect? Sind alle Pins am SID 
angeschlossen und alle Pegel richtig? usw. Das Picoscope 3206, was ich 
hier habe (und zwei Kanäle brauchst du, um z.B. die Signale relativ zum 
Chipselect oder Clock zu testen), kann ich wirklich empfehlen. Für dich 
würde allerdings auch die preiswertere 2203-Variante ausreichen, falls 
du nicht irgendwann mal was schnelleres messen willst.

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,

hast du schon den 1 MHz mal mit der Programmierung am SID getestet?
Vielleicht sind die 1,xx (s.o.) doch etwas zu hoch.

Stephan

von Peter (Gast)


Lesenswert?

Hallo Frank, aber durchaus auch die anderen :-)

Frank, du hast mir ja den Oszillator geschickt und dazu sogar noch auf 
dem Papier, wo der drauf gesteckt war vermerkt, was was ist. Leider weiß 
ich jetzt nicht mehr wie rum der drauf war.

Meine Frage: Ist der Pin mit Punkt auf dem Oszillator der Ausgang?

Wenn ja, dann würde sich der Rest ergeben; wenn nein würde sich der Rest 
auch ergeben :-)

Werde heute auf jeden Fall mal Nachtschicht einlegen (gähn) und schauen, 
ob nicht doch was zu machen ist...

Viele Grüße,
Peter

von Frank B. (foobar)


Lesenswert?

Nein, der Punkt kennzeichnet Pin 1. Wenn der links unten ist, dann ist 
der Ausgang rechts oben. Stromversorgung dann wie bei den meisten 
TTL-Chips: Links oben plus und rechts unten Masse.

von Peter P. (uncle-sam7)


Lesenswert?

Gute Nacht zusammen,

naja, bin echt gefrustet. Habe eben den 1MHz Oszillator angeschlossen. 
Nochmal mit meiner LED-Leiste alle Leitungen zum SID geprüft. Scheint 
so, als ob nix verdreht wäre. Allerdings das Selbe in grün. Nur ein 
Knacksen. Habe extra nochmal die Sound-Befehle im C64 Emulator getestet. 
Da sollte ein gleichmäßiger Ton rauskommen.

Ich denke, dass es irgendwie schon funktioniert. Wenn ich die Lautstärke 
über 0xD418 auf 15 setze, dann knackst es stärker, als wenn ich die 
Lautstärke auf 7 setze. Ich habe noch vom C64 in Erinnerung, dass da ein 
Kancksen war, wenn man die Lautstärke gesetzt hat. Bin mir allerdings 
nicht ganz sicher, ob das beim 8580 auch noch so war...

Hmmm was nun?

Kann es vielleicht an den Kondensatoren für die 2 Filer liegen?

Irgendwie habe ich das Gefühl, dass das mit der Lautstärke klappt, aber 
keine Töne erzeugt werden können...

Das wars dann wohl?

Peter

von Peter P. (uncle-sam7)


Lesenswert?

Hallo NG,

nochmal ein kleiner Nachtrag:

es scheint doch zu funktionieren. Allerdings habe ich wohl folgendes 
großes Problem: Sobald ich auf den SID zugreife entstehen scheinbar 
alleine durch den Zugriff Störgeräusche am Ausgang (ein Knacksen pro 
Zugriff). Habe eine Schleife am Ende Eingebaut, die die Frequenz des 
Tones erhöht. Im Hintergrung hört man diesen Ton ganz Leise. Im 
Vordergrund entsteht ein kontinuierlicher Ton durch die Störgeräusche 
beim Setzen der Leitungen am SID...

Momentan sieht der Code so aus:
1
#include "Board.h" 
2
#include "AT91SAM7S256.h"
3
4
#define LED1    BIT17
5
#define LED2    BIT18
6
#define BUTTON1    BIT19
7
#define BUTTON2    BIT20
8
9
#define SID_A0    BIT0
10
#define SID_A1    BIT1
11
#define SID_A2    BIT2
12
#define SID_A3    BIT3
13
#define SID_A4    BIT4
14
#define SID_RES    BIT5
15
#define SID_CLOCK  BIT6
16
#define SID_RW    BIT7
17
#define SID_CS    BIT8
18
19
#define SID_D0    BIT16
20
#define SID_D1    BIT23
21
#define SID_D2    BIT26
22
#define SID_D3    BIT27
23
#define SID_D4    BIT28
24
#define SID_D5    BIT29
25
#define SID_D6    BIT30
26
#define SID_D7    BIT31
27
28
#include "system.h"
29
#include "system.c"
30
31
// Pullups für die Datenleitungen und die Taktleitung deaktivieren
32
void pull_ups_fuer_sid_ausschalten(void)
33
{
34
  AT91C_BASE_PIOA->PIO_PPUDR = 
35
    SID_D0 +
36
    SID_D1 +
37
    SID_D2 +
38
    SID_D3 +
39
    SID_D4 +
40
    SID_D5 +
41
    SID_D6 +
42
    SID_D7 +
43
    SID_A0 +
44
    SID_A1 +
45
    SID_A2 +
46
    SID_A3 +
47
    SID_A4 +
48
    SID_CLOCK;
49
}
50
51
void poke(unsigned char adresse, char wert)
52
{
53
  // Bits maskieren, die gesetzt werden können
54
  p_pPio->PIO_OWER =
55
    SID_A0 +
56
    SID_A1 +
57
    SID_A2 +
58
    SID_A3 +
59
    SID_A4 +
60
    SID_D0 +
61
    SID_D1 +
62
    SID_D2 +
63
    SID_D3 +
64
    SID_D4 +
65
    SID_D5 +
66
    SID_D6 +
67
    SID_D7;
68
69
  wait_sid_cycles(1);
70
  // Datenleitung
71
  p_pPio->PIO_ODSR = 
72
    (((adresse & 1)/1)    * SID_A0) +
73
    (((adresse & 2)/2)    * SID_A1) +
74
    (((adresse & 4)/4)    * SID_A2) +
75
    (((adresse & 8)/8)    * SID_A3) +
76
    (((adresse & 16)/16)  * SID_A4) +
77
78
    (((wert & 1)/1)      * SID_D0) +
79
    (((wert & 2)/2)      * SID_D1) +
80
    (((wert & 4)/4)      * SID_D2) +
81
    (((wert & 8)/8)      * SID_D3) +
82
    (((wert & 16)/16)    * SID_D4) +
83
    (((wert & 32)/32)    * SID_D5) +
84
    (((wert & 64)/64)    * SID_D6) +
85
    (((wert & 128)/128)    * SID_D7);
86
87
    wait_sid_cycles(1);      
88
       p_pPio->PIO_CODR = SID_RW;    // our SID is write only
89
    p_pPio->PIO_CODR = SID_CS;
90
    wait_sid_cycles(1);      
91
    p_pPio->PIO_SODR = SID_CS;
92
}
93
94
void wait_sid_cycles(int cycles)
95
{
96
  while (cycles != 0)
97
  {
98
    while(!((p_pPio->PIO_PDSR) & SID_CLOCK))
99
    {
100
    }
101
    while(((p_pPio->PIO_PDSR) & SID_CLOCK))
102
    {
103
    }
104
    cycles--;
105
  }
106
}
107
108
void sid_reset(void)
109
{
110
  p_pPio->PIO_CODR = SID_RES;
111
  wait_sid_cycles(20);      // must wait at least 10 SID cycles
112
  p_pPio->PIO_SODR = SID_RES;
113
114
  p_pPio->PIO_CODR = SID_RW;    // our SID is write only
115
  p_pPio->PIO_SODR = SID_CS;    // CS High, Low on read / write
116
}
117
118
int main(void)
119
{
120
  char x;
121
  // init leds / usart0
122
  InitPeriphery();
123
  pull_ups_fuer_sid_ausschalten();
124
125
  p_pPio->PIO_CODR = LED1;
126
127
  AT91C_BASE_PIOA->PIO_PDR  = SID_CLOCK;  // Configure SID_CLOCK to be driven by peripheral
128
  AT91C_BASE_PIOA->PIO_OER  = SID_CLOCK;  // Configure SID_CLOCK as output
129
  AT91C_BASE_PIOA->PIO_PPUDR  = SID_CLOCK;  // Disable pull-up on SID_CLOCK
130
  AT91C_BASE_PIOA->PIO_BSR  = SID_CLOCK;  // Assign SID_CLOCK to peripheral B function
131
132
  AT91C_BASE_PMC->PMC_SCER |= 0x00000100;    // Enable PCK1
133
  AT91C_BASE_PMC->PMC_PCKR[0] = 1 + 16 ;    // Select Main Osc Output + Slow Clock
134
135
  // SID Reset erst möglich, nachdem Takt steht.
136
   sid_reset();
137
138
  while(1)
139
  {
140
    poke(0x18,15);
141
    p_pPio->PIO_CODR = LED1;
142
    wait_sid_cycles(100000);
143
    poke(0x00, 196);
144
    p_pPio->PIO_SODR = LED1;
145
    wait_sid_cycles(100000);
146
    poke(0x01, 9);
147
    p_pPio->PIO_CODR = LED1;
148
    wait_sid_cycles(100000);
149
    poke(0x05, 94);
150
    p_pPio->PIO_SODR = LED1;
151
    wait_sid_cycles(100000);
152
    poke(0x06, 71);
153
    p_pPio->PIO_CODR = LED1;
154
    wait_sid_cycles(100000);
155
    poke(0x04, 33);
156
    p_pPio->PIO_SODR = LED1;
157
    wait_sid_cycles(100000);
158
159
    while(1)
160
    {
161
      poke(0x01, x);
162
      x++;
163
      wait_sid_cycles(2000);
164
    }
165
  }
166
}

von Frank B. (foobar)


Lesenswert?

Poste mal den Schaltplan von deiner bisherigen Schaltung, vielleicht 
fällt ja einem was auf.

Hast du einen 6581 oder 8580? Wenn man so im Internet sucht, scheinen 
die übrigens alle bei Vdd 12 V (6581) oder 9 V (8580) angeschlossen zu 
haben, die hast du auch anliegen? Achtung: Vcc natürlich weiterhin 5 V.

Wegen den beiden Filterkondensatoren an CAP1A/1B und CAP2A/2B denke ich 
ist nicht kritisch, solange du die Filter nicht einschaltest, aber man 
kann ja nie wissen. 470 pF für den 6581 und 22 nF für den 8580.

Wie hörst du den Audio Out ab? Muß ein hochohmiger Anschluss sein, also 
kein normaler Kopfhörer oder gar Lautsprecher. Hier in der Schaltung:

http://www.ucapps.de/mbhp/mbhp_sid_v3.pdf

wird es nur mit 10 k belastet und per Transistor verstärkt.

von Peter P. (uncle-sam7)


Lesenswert?

Frank Buss schrieb:
> Poste mal den Schaltplan von deiner bisherigen Schaltung, vielleicht
> fällt ja einem was auf.

Also ich habs momentan 1:1 wie es in
http://www.zimmers.net/anonftp/pub/cbm/schematics/computers/c128/manual/46.gif
steht angeschlossen. (o) Audio-Out (nach dem Kondensator) ist bei mir 
eine Kopfhöhrerbuchse, die ich an einen aktiven PC-Speaker angeschlossen 
habe...

> Hast du einen 6581 oder 8580? Wenn man so im Internet sucht, scheinen
> die übrigens alle bei Vdd 12 V (6581) oder 9 V (8580) angeschlossen zu
> haben, die hast du auch anliegen? Achtung: Vcc natürlich weiterhin 5 V.

Das mit den 9V habe ich in meinem Fall beachtet. Die liegen auch an. An 
den beiden Versorgungspins habe ich noch die Bypasses installiert.

> Wegen den beiden Filterkondensatoren an CAP1A/1B und CAP2A/2B denke ich
> ist nicht kritisch, solange du die Filter nicht einschaltest, aber man
> kann ja nie wissen. 470 pF für den 6581 und 22 nF für den 8580.

hmm. Ich hab die Kondensatoren wie in
http://www.zimmers.net/anonftp/pub/cbm/schematics/computers/c128/manual/46.gif
gewählt...

> Wie hörst du den Audio Out ab? Muß ein hochohmiger Anschluss sein, also
> kein normaler Kopfhörer oder gar Lautsprecher. Hier in der Schaltung:
>
> http://www.ucapps.de/mbhp/mbhp_sid_v3.pdf
>
> wird es nur mit 10 k belastet und per Transistor verstärkt.

Irgendwie hab ich echt fast keine Lust mehr irgendwas da anzuschließen. 
Bin echt total gefrustet deswegen. Mal schauen, vielleicht nächstes 
WE...

von Frank B. (foobar)


Lesenswert?

Die Störgeräusche sollten eigentlich nicht lauter als das Signal sein, 
so schlecht war der SID ja nun auch wieder nicht :-) Versuche doch 
einfach mal, die gesamte poke-Sequenz in deine Schleife mit aufzunehmen. 
Die 10 Takte Verzögerung nach dem Reset könnten vielleicht was knapp 
sein, oder vielleicht wird zwischendurch mal nicht richtig geschrieben, 
sodaß z.B. das Lautstärkeregister nicht gesetzt wird.

Ohne Scope wirst du da nicht mehr viel machen können. Hier hatte z.B. 
einer so ein Problem:

http://midibox.org/forums/topic/5350-oscillator-troubles-was-re-sid-as-a-drum-machine/

Sollte zwar nur recht selten einen Fehler verursachen, aber vielleicht 
bist du ja gerade irgendwo auf der Grenze vom Timing und liegst genau an 
der falschen Stelle, sodaß dein poke generell unzuverlässig ist.

von Peter P. (uncle-sam7)


Lesenswert?

Ich hatte gerade eine (geniale) Idee:

Irgendwie hat mich das Brummen an die Art erinnert, die ich früher mal 
mit nem Mantelstromfilter eliminiert habe.

Auf meinem Olimex-Board werden ja die 5V und 3,3V "von Haus aus" 
angeboten. Die 9V hole ich über ein justierbares Steckernetzteil. Das 
habe ich eben durch den 9V Block meines Messgeräts ausgetauscht. Siehe 
da: Ich höre leise SID-Töne ohne Störgeräusche. Allerdings wirklich 
extrem leise... Hmm jetzt ist leider schon nach 12.00 und ich habe die 
Bauteile nicht besorgt :-(

Klingt auf jeden Fall jetzt doch wieder vielversprechend. Jetzt muss ich 
mir dann langsam mal gedanken machen, wo ich die 9V sauber herbekomme, 
so dass ich die auch ins Bord "einspeisen" kann, ohne dass Störungen 
auftreten...

MfG
Peter

von Frank B. (foobar)


Lesenswert?

Am besten wäre wohl, wenn du die 5 V verwendest, um daraus die 9 V zu 
machen, denn dann brauchst du kein externes Netzteil. Gibt da preiswerte 
DC/DC-Wandlerchips. Da das aber Schaltregler sind, die Störungen 
verursachen könnten, vielleicht auf 12 V wandeln und danach noch einen 
LM317 Linearregler, oder 7809 o.ä. schalten, der das dann auf 9 V 
wandelt.

Ist aber schon merkwürdig, daß es so leise ist. Hast du mal gemessen, 
was am Audio-Ausgang rauskommt, mit dem Aktiv-Speaker als Last und ohne? 
Ein Multimeter müsste den Wechselstrom ja messen können. Aber vielleicht 
ist die Ausgangsstufe des SIDs auch einfach kaputt.

von Peter P. (uncle-sam7)


Lesenswert?

Frank Buss schrieb:
> Ist aber schon merkwürdig, daß es so leise ist.

Denkst Du nicht, dass die Verstärkerschaltung (midibox), die in dem 
Schaltplan ist, den Du mit gepostet hast das soweit anhebt, dass alles 
OK ist?

> Hast du mal gemessen,
> was am Audio-Ausgang rauskommt, mit dem Aktiv-Speaker als Last und ohne?
> Ein Multimeter müsste den Wechselstrom ja messen können. Aber vielleicht
> ist die Ausgangsstufe des SIDs auch einfach kaputt.

Sorry, hier kommt wieder mein "Mr. just left hand" in Sachen Elektronik 
durch. Wie genau würdest Du die Messung machen?
Direkt an der Buchse (nach dem Kondensator), oder davor? Parallel?

Min Multimeter hat
  ___
A - - -

Wechselstrom müsste dann

A ~

sein, oder? A ~ hab ich leider nicht...

Wenn die Ausgangsstufe kaputt ist, sollte dann nicht gar nichts 
rauskommen?
Wenn sie kaputt ist, dann muss es aber während meiner Bastelarbeiten 
passiert sein, da der vorher im 128er noch funktioniert hat.

Wg. der 9V, 5V und 3,3V: z.Zt habe ich das Board ja über USB 
angeschlossen (abgesehen von den 9V keine weiteren Einspeisungen (auch 
nicht über den 6V Eingang am Board.)) Sollte es dann nicht am 
geeignetsten sein, dass ich 9V als Grundversorgung nehme, und über den 
USB-Port später nur noch 5V Einspeise, so dass alles so ist, wie wenn 
das Board am PC hängt?

D.h. die 5V von den 9V reduzieren?

MfG
Peter

von Frank B. (foobar)


Lesenswert?

Wenn es um Analogtechnik geht, dann weiss ich auch nicht besonders 
Bescheid. Aber die Schaltung sieht mir nur nach einem Impedanzwandler 
aus:

http://www.elektronikinfo.de/strom/emitterfolger.htm

Hat also keine Spannungsverstärkung, sondern sorgt nur dafür, daß man an 
den Ausgang was niederohmigeres anschliessen kann, z.B. direkt ein 
Kopfhörer.

Mit der Messung meinte ich, die Leerlaufspannung messen, nicht den 
Strom, denn das würde den Ausgang kurzschließen, habe mich da falsch 
ausgedrückt. Also Multimeter auf Wechselspannung einstellen, falls es 
das nicht automatisch erkennt, Aktiv-Speaker nicht einstecken und einen 
Ton messen, dann Aktiv-Speaker einstecken und nochmal messen. Wenn die 
Spannung zu sehr abfällt, dann hat der Aktiv-Speaker einen zu kleinen 
Eingangswiderstand und belastet das Signal zu stark, sodaß es zu leise 
wird (kann ich mir aber eigentlich nicht vorstellen, normalerweise sind 
die relativ hochohmig).

Mit den 9 V kannst du natürlich als Basis nehmen. Würde wahrscheinlich 
auch eine gute Idee sein, wenn du das Board mal ohne PC betreiben 
willst. Kann aber sein, wenn das ungeregelt ist, daß dann Störgeräusche 
eingekoppelt werden, also vielleicht 12 V als Basis nehmen und das dann 
auf 5 V und 9 V mit zwei Linearspannungsreglern regeln.

von Peter P. (uncle-sam7)


Lesenswert?

Hello again,

kurzes Update:

Ich werde nun noch ein letztes Mal Zeit investieren. Mein Plan: den 
SID-Part 1:1 wie in

http://htmlimg3.scribdassets.com/6nvi632f9c2tj6y/images/83-bc90db2efb/000.jpg

aufbauen. Wenns dann nicht funkt, dann weiß ich auch nicht mehr 
weiter...
Melde mich, sobald alles aufm Steckbrett ist (und hoffentlich 
funktioniert).

MfG
Peter

von Peter P. (uncle-sam7)


Angehängte Dateien:

Lesenswert?

Hallo NG,

so, jetzt sind wieder ein paar Tage ohne Zeit vergangen. Habe nun den 
kompletten "SID-Teil" der alten 128D Platine "extrahiert" un auf 
Lochraster übertragen. Am WE muss ich noch nen Sockel für den SID kaufen 
und dann werde ich den ganzen Summs mal anschließen und hoffen, dass es 
diesmal lauter ist. Wenn nicht, denke ich, dass der SID im Eimer ist. 
Ich hatte zwar die Frage schon mal etwas weiter oben gestellt, aber 
nachdem die alten Bauteile etwas anders aussehen, würde ich sie gerne 
nochmal fragen:

Die Einbaurichtung der auf dem Bild markierten Bauteile sollte doch egal 
sein? Kann das leider nicht mehr rekonstruieren...

Und noch eine weitere Frage: Was macht denn der Kondensator zwischen E + 
B beim Transistor?

Und vielleicht noch eine weitere: Was würde es denn ungefär kosten, eine 
Platine anfertigen zu lassen, wo der AT91SAM7 + SID und Zubehör verbaut 
ist? Selbst bestücken dürfte bei den kleinen Beinchen eher unmöglich 
sein, oder? Gibts da evtl. Adapter-Sockel?

Viele Grüße - bis zum Wochenende mit hoffentlich Soundbeispiel im Anhang 
des nächsten Posts...

Peter

von Frank B. (foobar)


Lesenswert?

Du meinstest doch, in dem C128 würde der SID noch funktionieren? 
Vielleicht einfach den Audio-Verstärker aufdrehen? Hattest du mal die 
Wechselspannung mit und ohne den Verstärker als Last gemessen? Die 
Transistorstufe sollte das aber lösen, falls das Problem ein zu 
niederohmiger Eingang deines Aktiv-Speakers ist.

Die Einbaurichtung der markierten Teile ist egal, das sind 
Keramikkondensatoren, die keine Polarität haben. Anders als Elkos, die 
dir um die Ohren fliegen können, wenn du die falschrum einbaust. Keine 
Ahnung was der Kondensator zwischen B und E macht, ist wieder 
Analogtechnik.

Eine Platine kannst du z.B. mit Eagle erstellen ( http://www.cadsoft.de/ 
) und bei PCB-Pool anfertigen lassen, die mittlerweile auch einen nicht 
allzu teuren Bestückungsservice anbieten.

ICs in QFP-Bauform kann man aber auch problemlos selber löten:

http://www.youtube.com/watch?v=5uiroWBkdFY

Ab 1:50 in dem Video siehst du, wie Profis das machen. Habe ich so 
leider bisher noch nicht geschafft, aber die Pins per dünner 1 mm 
Lötspitze einzeln unter meinem Stereomikroskop anzulöten ist kein 
Problem. Für den SAM7 Könnte man diesen Adapter nehmen:

http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=350233589737

Man kann auch ganz ohne Adapter die Dead-Bug Technik (weil auf dem 
Rücken liegender Käfer) anwenden:

http://www.frank-buss.de/tmp/dead-bug.jpg

Allerdings wird das bei vielen Pins und vielen nötigen Anschlüssen 
schnell unübersichtlich.

Eine andere Technik ist, eine kupferkaschierte Platine zu nehmen, dann 
per Handbohrer Stege reinfräsen und dann anlöten:

http://www.frank-buss.de/tmp/m41t82.jpg

Ja, sieht abenteuerlich aus, hat aber tatsächlich funktioniert :-)

Profis machen das aber per Reflow-Löten. PCB-Pool bietet da auch was für 
den Hobbygebrauch an: man kann dort kostenlos ein Stencil für eine in 
Auftrag gegebene Platine mitbestellen. Mit dem PCB-Pool Reflow Ofen (ein 
normaler Pizza-Ofen, mit externer Steuerlogik und Temperatursensor) kann 
man dann auch komplexere Platinen schnell und sauber selber bestücken:

http://www.frank-buss.de/reflow/

Damit habe ich schon erfolgreich einen Prototypen einer Platine mit 
dutzenden von SMD-Bauteilen, TSSOP und QFP Bauteilen und einem 
DIMM-Sockel für ein kommerzielles Projekt mit gebacken.

Mit gaaaaaaanz viel Übung kann man sogar BGAs von Hand auslöten und 
wieder einlöten:

http://www.youtube.com/watch?v=JB1InDsWCjQ

So eine Heissluftstation hilft generell, wenn mal was schiefgeht, oder 
man auch mal an die nicht gesockelten ICs im C64 rankommen will. Hier 
mal ein Video, daß ich vor einiger Zeit aufgenommen habe:

http://www.youtube.com/watch?v=Y7BGzSP_XP8

von Peter (Gast)


Lesenswert?

Hallo Frank,

Frank Buss schrieb:
> Du meinstest doch, in dem C128 würde der SID noch funktionieren?
naja, zumindest weiß ich, dass das schon mal der Fall war :-) Hab schon 
so manches Bauteil "kaputt gelötet".

> Vielleicht einfach den Audio-Verstärker aufdrehen? Hattest du mal die
> Wechselspannung mit und ohne den Verstärker als Last gemessen? Die
> Transistorstufe sollte das aber lösen, falls das Problem ein zu
> niederohmiger Eingang deines Aktiv-Speakers ist.
Naja, ich habe schon kräftig aufgedreht. Das Messen habe ich jetzt nicht 
mehr gemacht. Es waren einfach zu viele Unklarheiten für mich (z.B. 
könnte es an den Filterkondensatoren liegen...). Diese Unklarheiten habe 
ich jetzt zumindest mal dadurch aufgelöst, dass ich einfach die 
Original-Bauteile genommen habe :-) Wenns jetzt nicht klappt, würde ich 
stark dazu tendieren, dass der SID das Zeitliche gesegnet hat...

> Die Einbaurichtung der markierten Teile ist egal, das sind
> Keramikkondensatoren, die keine Polarität haben. Anders als Elkos, die
> dir um die Ohren fliegen können, wenn du die falschrum einbaust.
das beruhigt mich jetzt schon wieder. Bei den Elkos und den anderen 
Teilen habe ich aufgepasst.

> Keine Ahnung was der Kondensator zwischen B und E macht, ist wieder
> Analogtechnik.
Hmm, muss da mal googlen... Irgendwie find ich Elektronik total 
interessant, auch wenn ich keine Ahnung davon habe. Habs auch schon mal 
mit nem Experimentierkasten für Kinder probiert. Vielleicht sollte ich 
das irgendwann nochmal machen.

> Eine Platine kannst du z.B. mit Eagle erstellen
> und bei PCB-Pool anfertigen lassen, die mittlerweile auch einen nicht
> allzu teuren Bestückungsservice anbieten.
muss ich mir mal ansehen. Gibts eigentlich auch Freeware-Programme zum 
Layouten?

> ICs in QFP-Bauform kann man aber auch problemlos selber löten:
Das ist ja heftig. Ich denke das muss man das ein oder andere Mal üben, 
wenn man nicht alle Beinchen verbunden haben möchte?

> Ab 1:50 in dem Video siehst du, wie Profis das machen. Habe ich so
> leider bisher noch nicht geschafft, aber die Pins per dünner 1 mm
> Lötspitze einzeln unter meinem Stereomikroskop anzulöten ist kein
> Problem. Für den SAM7 Könnte man diesen Adapter nehmen:
ja genau, sowas meinte ich prinzipiell. Gibt es den AT91SAM7 eigentlich 
auch so als "Clip In". Habe da so Sockel im Kopf, wo man die Chips 
einfach reinsteckt (ohne zu löten). Kontakte sind glaube ich immer außen 
am Gehäuse? Wie nennt man denn sowas?


> Man kann auch ganz ohne Adapter die Dead-Bug Technik (weil auf dem
> Rücken liegender Käfer) anwenden:
> http://www.frank-buss.de/tmp/dead-bug.jpg
> Allerdings wird das bei vielen Pins und vielen nötigen Anschlüssen
> schnell unübersichtlich.
Hut ab meine Herren. Ich glaube mit meinem 5€ Lötkolben wäre der schnell 
in echt Tot :-)

> Eine andere Technik ist, eine kupferkaschierte Platine zu nehmen, dann
> per Handbohrer Stege reinfräsen und dann anlöten:
> http://www.frank-buss.de/tmp/m41t82.jpg
Nicht übel.

> Profis machen das aber per Reflow-Löten. PCB-Pool bietet da auch was für
> den Hobbygebrauch an: man kann dort kostenlos ein Stencil für eine in
> Auftrag gegebene Platine mitbestellen. Mit dem PCB-Pool Reflow Ofen (ein
> normaler Pizza-Ofen, mit externer Steuerlogik und Temperatursensor) kann
> man dann auch komplexere Platinen schnell und sauber selber bestücken:
> http://www.frank-buss.de/reflow/
Hier kann man ja echt noch was lernen :-) Was es nicht alles gibt...

> Damit habe ich schon erfolgreich einen Prototypen einer Platine mit
> dutzenden von SMD-Bauteilen, TSSOP und QFP Bauteilen und einem
> DIMM-Sockel für ein kommerzielles Projekt mit gebacken.
> Mit gaaaaaaanz viel Übung kann man sogar BGAs von Hand auslöten und
> wieder einlöten:
> http://www.youtube.com/watch?v=JB1InDsWCjQ
Naja, ganz viel übung habe ich vielleicht, wenn ich die 128er Platine 
komplett entlötet habe (was sehr wahrscheinlich nicht vorkommen wird)

> So eine Heissluftstation hilft generell, wenn mal was schiefgeht, oder
> man auch mal an die nicht gesockelten ICs im C64 rankommen will. Hier
> mal ein Video, daß ich vor einiger Zeit aufgenommen habe:
> http://www.youtube.com/watch?v=Y7BGzSP_XP8
Bei meiner Ausstattung würde ich wahrscheinlich zum Fön aus dem 
Badezimmer greifen :-)

Melde mich auf jeden Fall am WE nochmal...
Gruß Peter

von Frank B. (foobar)


Lesenswert?

Eine geregelte Lötstation solltest du schon haben, wenn du was mehr 
Löten willst, z.B. auch Platinen mit QFP ICs und anderen SMD-Bauteilen. 
So ein 5 Euro Lötkolben aus dem Baumarkt kann meist auch nicht genug 
Leistung nachliefern, sodaß man immer wieder warten muß, bis er wieder 
wärmer wird. Ich habe hier die iCon 1 von Ersa und damit macht das 
wirklich Spaß. Man kann damit auch mal größere Masseflächen löten, ohne 
stundenlang auf einer Stelle herumbraten zu müssen, da die eingestellte 
Temperatur an der Spitze auch bei sehr unterschiedlicher Wärmeableitung 
sehr gut gehalten wird.

Ein Heisstluftgerät brauchst man nicht unbedingt, hauptsächlich zum 
Entlöten. Aber ein Fön mit 400°C habe ich noch nicht gesehen :-)

Mit diesen Clip-Chips meinst du vermutlich PLCC:

http://de.wikipedia.org/wiki/Plastic_Leaded_Chip_Carrier

Gibt es aber für den Atmel glaube ich nicht. Wenn du es kleiner als dein 
Evalkit haben willst, wäre wohl noch am einfachsten sowas hier:

http://olimex.com/dev/sam7-h256.html

Eagle ist übrigens für Hobbyverwendung kostenlos, mit ein paar 
Beschränkungen. Sonst kann ich KiCad und gEDA ( 
http://www.gpleda.org/index.html ) noch empfehlen. Für so ein kleines 
Projekt wie deinen SID-Player kannst du aber alle drei Programme nehmen.

Eagle ist allerdings manchmal ein wenig umständlich zu bedienen, wenn 
man eher Windows-Programme gewöhnt ist, aber ich verwende das schon seit 
DOS-Zeiten und habe mich daran gewöhnt. Im Gegensatz zu Evalversionen 
von teureren kommerziellen PCB-Programmen ist mir Eagle auch noch nie 
abgestürzt und die direkte Nachführung von Änderungen im Schaltplan auf 
dem Board finde ich auch komfortabler, als bei manch anderen Programmen, 
wo man das in einem extra Schritt synchronisieren muß.

von Peter P. (uncle-sam7)


Angehängte Dateien:

Lesenswert?

Hallo Frank,

habe eben alles fertig gelötet und angeschlossen.
Angeschalten, Programm in den Speicher geladen und go...

Leider überhaupt kein Geräusch zu hören!

Ein bischen blind durch die Gegend gemessen. Aber auch nicht wirklich 
was gefunden; bis auf: Eine Verbindung zwischen erstem Widerstand am 
Ausgangspin und dem ersten Bypass fehlt. Lötkolben nochmal angesteckt.

Und siehe da:

:-) :-) :-) :-) :-) :-)
J U H U U U U U U ! ! !
:-) :-) :-) :-) :-) :-)

Ich fass es nicht! Kein Brummen, kein Rauschen nur allerfeinste 
SID-Töne. Am Verstärker die Lautstärke stimmt auch mit dem überein, was 
ich zu hören bekomme.

Also nochmal vielen Dank, an alle, die konstruktiv zur Lösung 
beigetragen haben. Besonders an Frank, dessen Oszillator hier genial 
funktioniert!

So, die nächsten Schritte wären dann folgende:
1) den Emulator mit dem Zeug hier "verheiraten", was mir wohl als
   Programmierer leichter fallen wird, als die Schaltung hier...
   Im ersten Schritt mit einem "festen" SID-Stück im Speicher
   (SuperHuey) dabei auch schon mal am timing "schrauben".
2) HD44870 anschließen. Die beiden Knöpfe des Boards verwenden. Menü.
   SIDs von SD-Card laden.
3) am Ende dann alles für den EEPROM Speicher anpassen und draufladen.
4) Gehäuse bauen
5) Internetseite aktualisieren :-)

PS: Bin jetzt auch ein kleines bisschen stolz auf mich, dass ich das 
anhand des Schaltplans gelötet habe und nur 1x nachbessern musste (wo 
ich doch von den Schaltplänen nicht viel verstehe :-)

Weiß zufällig jemand, wieviel langsamer Programme im EEPROM ausgeführt 
werden, als im SRAM?

So, jetzt kann ich endlich ruhig schlafen freu

von Frank B. (foobar)


Lesenswert?

Schön, daß es läuft. Poste hier mal kurz in diesem Thread, wenn du 
weiter mit der Software bist. Ich habe ja auch noch einen alten C64 
hier, mit gesockeltem SID, vielleicht baue ich das dann auch mal nach.

Programm aus dem Flash auführen geht mit Waitstates (bei schnellen Chips 
1 Waitstate), aber ich glaube der SAM7 hat auch noch einen internen 
Instruction-Cache, sodaß es insgesamt nicht viel langsamer sein sollte. 
Bei kritischen Dingen, und ausreichend SRAM, kann man auch einfach das 
Programm beim Startup aus dem Flash ins SRAM kopieren (ok, "einfach" war 
ein wenig euphemistisch, aber es geht :-)

von Peter P. (uncle-sam7)


Lesenswert?

> Schön, daß es läuft. Poste hier mal kurz in diesem Thread, wenn du
> weiter mit der Software bist. Ich habe ja auch noch einen alten C64
> hier, mit gesockeltem SID, vielleicht baue ich das dann auch mal nach.

Ja, mach ich. Der gesockelte SID wird laut "Lizenzbedingungen" eh 
Pflicht. Ich will ja nicht ein C64/C128-Ausschlachten vorantreiben :-)

> Programm aus dem Flash auführen geht mit Waitstates (bei schnellen Chips
> 1 Waitstate), aber ich glaube der SAM7 hat auch noch einen internen
> Instruction-Cache, sodaß es insgesamt nicht viel langsamer sein sollte.

hört sich gut an.

> Bei kritischen Dingen, und ausreichend SRAM, kann man auch einfach das
> Programm beim Startup aus dem Flash ins SRAM kopieren (ok, "einfach" war
> ein wenig euphemistisch, aber es geht :-)

hab das schon mal gesehen. Ich glaube man kann dem Compiler irgendwie 
sagen, dass eine Funktion als FASTRUN/RAMFUNC gehalten wird. Dabei habe 
ich aber nach wie vor das Problem, dass ich von den 64KB SRAM des 
AT91SAM7S so wenig wie möglich nutzen möchte, da dieser Speicher (fast) 
ausschließlich für den 64er-Speicher vorgesehen ist.

von Peter Pippinger (Gast)


Lesenswert?

Hallo NG,

habe gestern noch den Emulator mit der Hardware "verheiratet". An der 
Software habe ich noch geändert, dass der 1MHz Takt auch am Pin des 
AT91SAM7 anliegt. Dann nehme ich den als Referenz für die Emulation.

Ist das eigentlich technisch OK, wenn der Takt vom Oszillator sowohl in 
den SID als auch in den AT91SAM7 geht (parallel und ohne Widerstände 
etc...)

Es funktioniert jetzt alles. Hatte noch kleine Anlaufschwierigkeiten, da 
ich versucht habe, die Daten und Adressleitungen am Ende wieder "zu 
löschen", was ja gar niocht nötig ist, da CS ja Verantwortlich ist... 
Vom Timing her bin ich auch geizig. 1 Flankenwechsel fürs Schreiben 
reicht.

SuperHuey wird jetzt korrekt abgespielt. Ich muss erst noch ein 
Verbindungskabel zum PC kaufen, dann kann ich hier mal einen Soundfile 
anhängen.

Ich denke, die Chancen stehen gut, dass das Ganze auch noch rel. 
Taktgenau funktionieren wird. Werde noch versuchen, ein aufwendigeres 
Lied reinzuhacken. Dann poste ich mal die erste Version des Codes.

MfG
Peter

von Frank B. (foobar)


Lesenswert?

Sollte kein Problem sein, den Quarzoszillator an beide Chips 
dranzuhängen. Ist ja sowas hier:

http://www.reichelt.de/?ACTION=3;ARTICLE=13673;PROVID=2402

Der kann also problemlos 2 TTL oder 10 LS-Gatter treiben. Und von den 
Atmel CMOS-Eingängen wahrscheinlich noch ein paar mehr.

SuperHuey kenne ich nicht, hast du ein SID-File dafür?

Ich kann mich noch an Supremacy erinnern:

http://www.youtube.com/watch?v=Rln4K1NdJdo

wobei klang auf dem Amiga noch besser.

Eine schöne Sammlung:

http://www.youtube.com/watch?v=bf62lbxVnQY

An den Tetris-Sound kann ich mich noch erinnern und ist immer noch sehr 
gut. Und natürlich Giana Sisters von Chris Hülsbeck, und bei der Musik 
von Jeroen Tel zum Outrun Rennautospiel glaubt man kaum, daß man sowas 
aus dem SID rausholen kann.

Könnte man übrigens nicht einfach die SID-poke-Befehle mit dem Emulator 
aufzeichnen und dann auf einem recht einfachen Microcontroller-System 
abspielen? Habe noch ein paar PICs und SD-Card Adapter hier rumliegen, 
die nichts zu tun haben, und auch einen alten C64 :-)

von Peter (Gast)


Lesenswert?

Hallo Frank,

also gestern habe ich noch Sanxion von Rob Hubbard zum Laufen gebracht. 
Das war auch ein geniales Stück.

Werde am WE mal alles zusammenpacken und Dir schicken.

Ist allerdings noch preAlpha :-)

Aber abspielen tut er 100% korrekt. Jetzt kommen halt noch die 
Feinheiten, die durchaus auch ihre Zeit brauchen.

Die Pokes für den SID abspielen, habe ich schon in einem anderen Thread 
hier gelesen. Ist halt evtl. Speicherintensiver als das Programm selbst. 
Aber natürlich daduch auch sehr Rechenunintensiv...

Also bis zum WE dann...
MfG
Peter

von Peter (Gast)


Lesenswert?

...achso, mir ist eben noch eingefallen, dass die beim SID-Stick (das 
Teil, das auf einem Parallax Propeller basiert) das auch so machen 
(soweit ich mich erinnern kann), dass die die "Pokes" an den SID 
abspielen. Dann müssen die sich nur noch um die SID-Emu kümmern. Da war 
auch irgendwo ein Programm, dass genau diese Daten "extrahiert". 
Vielleicht hilfts ja weiter...

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Frank,

als Nächstes wollte ich das Display anschließen.
Meinst Du, dass es funktioniert, wenn ich die 8 Datenleitungen des SIDs 
auch für den HD44780 verwende?
Kann ich die einfach parallel anschließen?
CS vom SID müsste ja ausschließen, dass da ungewünschte Daten am SID 
ankommen, oder?
Mir ist klar, dass dann auf jeden Fall immer nur einer was machen kann. 
Aber mit den Pins ist es echt knapp geworden. Lieber habe ich noch für 
die Bedienung ein paar Buttons mehr. Die 4Bit Ansteuerung bringt mich in 
diesem Fall auch nicht wirklich weiter.
RS RW und E des LCD würde ich dann auf noch freie Pins verlegen...

Für die SD-Card: Sehe ich das richtig, dass ich im Minimalfall nur 4 
Pins benötige (PA11-14). Die Abfrage, ob ne Karte vorhanden ist und ob 
Writeprotected ist mir eigentlich egal in diesem Fall.

Viele Grüße,
Peter

von Frank B. (foobar)


Lesenswert?

Sollte gehen mit HD44780. Das dann aber mit 5 V betreiben, da wenn du 
den SID mal lesen willst, das Display ja parallel dran hängt und es 
sonst vielleicht Probleme geben kann, wenn das Display mit 3,3 V 
versorgt wird und dann 5 V an den Datenleitungen vom SID bekommt.

Das Projekt habe ich erhalten, kann aber keins der SID-Dateien unter 
at91sam7p256\src\tools abspielen. Habe es mit sidplay 2 versuchst, was 
sonst bei vielen anderen SID-Dateien funktioniert.

Das mal auf dem Atmel auszuprobieren werde ich vielleicht nächste Woche 
zu kommen.

von Peter (Gast)


Lesenswert?

Die SIDs in dem Ordner hätte ich eigentlich umbenennen sollen. Es sind 
eigentlich keine SIDs mehr. Vielmehr habe ich mit den C64 Datenbereich 
aus den entsprechenden SID-Files mit HxD rausgeschnitten und 
abgespeichert. Diese Daten wandle ich dann mit dem PHP-Tool in dem 
Verzeichnis in Werte um, aus denen ich direkt das Array in C aufbauen 
kann (z.B. 255, 73, 63, 33 ...). Dieses Array wird dann per .ld-Skript 
direkt an die entsprechende Stelle im Speicher für den AT91SAM7 
"gelegt".

Ich habe das quick & dirty gemacht, da ich den SID-Header jetzt noch 
nicht auswerten wollte. Das mache ich dann, wenn ich das Zeug von 
SD-Karte lade. Mir war erstmal wichtig, dass die Hardware funktioniert.

Die SIDs sind übrigens einfach aus der HVSC-Collection 
(http://www.hvsc.de/)

Ich habe sowieso meine Strategie bzgl. des Speichers leicht geändert. 
Hab mal alle SIDs der Collection nach größe sortiert. Es sind nicht so 
viele dabei, die > 50KB sind. Ich denke, dass ich eher ein Array 
irgendwo im Speicher des ARM haben werde und dann jeweils die 
Loading-Adresse zu den adressrelevanten Befehlen addiere. Dem 64er Stack 
spendiere ich einen extra Bereich... Mal sehen, ob das eine gangbare 
Methode ist. Hab eigentlich ein ganz gutes Gefühl dabei.

von peter (Gast)


Lesenswert?

Hallo NG,

so, jetzt habe ich seit langem mal wieder ein wenig Zeit gehabt.

Bin zu dem Schluss gekommen, dass "premature optimization" die Wurzel 
allen Übels ist. Was für eine Erkenntnis :-)

Naja, nachdem ich ja die SID-Lieder wirklich gerne höre, habe ich mir 
gedacht, dass es nicht verkehrt sein kann, das Ding jetzt endlich erst 
mal fix und fertig zu machen. Firmware kann ja dann immer noch anders 
werden.

Assembler habe ich mal eben zur Seite geschoben (aber nicht in die 
Tonne!) und überlegt, wass ich an dem C-Konstrukt ändern muss...

Habs jetzt in etwa so gemacht:
SID wird in das Array geladen (keine Linker-Anpassungen mehr nötig)

static unsigned char memory[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 248, 48, 46, 80, 67, 162...

für den Stack und die Zeropage habe ich auch ein Array mit 512 Bytes.

für die SID-Register habe ich ein 29 Bytes Array. Zusätzlich werden die 
Werte auch gleich an den SID übertragen.

Dachte mir, das funktioniert gut so. Hab 5 Lieder getestet und die haben 
funktioniert. Allerdings lief eins nicht. Das lag daran, dass die auch 
Speicher adressiert haben, der weder im Stack noch in der Zeropage, noch 
in den Sidfiles, noch in den Sidregistern lag.

Als Workaround (ich hasse das) habe ich ein Array geschaffen, das für 
solche Speicherbereiche dann als Quelle und Ziel herhalten muss. Das 
Ganze noch über einen Modulus gesichert und siehe da, auch dieses Lied 
läuft. Aus dem Bauch raus würde ich sagen, dass ich damit einen Großteil 
der Songs erschlagen habe...

Werde mich jetzt dann langsam mal an das Gehäuse wagen. Würde da gerne 
ein Gehäuse aus (schönem) Holz bauen.

von peter (Gast)


Lesenswert?

So, werde das Teil wohl ab 08.03. auf nem LPC3131 weiterentwickeln. Die 
64 KB des SAM7S256 sind mir leider zu wenig. Wenn, dann sollten schon 
alle Files laufen.

Bis dahin schon mal eine ALPHA-Version
http://www.youtube.com/watch?v=hp69N3DZ6uA

Grüße,
Peter

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Freunde der guten Musik,

wollte nochmal ein kleines Update liefern:
ich denke zum Wohle meiner Frau verzichte ich lieber auf den LPC3131.

Mittlerweile läuft alles was ich brauche auf dem AT91SAM7S256.

mit dem Workaround (2 weiter oben) funktionieren eigentlich auch recht 
anspruchsvolle Lieder. Und nachdem es ja Tausende gibt, ist es nicht 
allzu schlimm, wenn das ein oder andere Lied nicht läuft...

Datenleitungen SID und HD44780 sind zusammengelegt.

Ich habe nicht mal mehr Lust gehabt, einen zusätzlichen Taster 
anzulöten. Dann habe ich mich entschlossen, wenn beide Taster gedrückt 
sind, das dann als "Enter" zu interpretieren. Funktioniert auch gut, 
nachdem die Auswertung erst stattfindet, wenn beide Taster losgelassen 
werden.

SD-Karte läuft auch schon. Muss nur noch ein C# Programm schreiben, das 
alle Lieder aus der HVSC auf "mein" Filesystem umwandelt (einfach 
Sektoren beschreiben). Da werden dann bei jeder Datei folgende 
Zusatzinfos gespeichert:

Sektor nächstes Lied
Sektor vorheriges Lied
Sektor nächster Künstler
Sektor vorheriger Künstler
und vielleicht noch andere Dinge...

Find ich ne ganz gute Idee. Erspart dann die Sucherei auf dem MC.

Naja, das wars dann auch schon wieder.

Bis später, Peter.

von Frank B. (foobar)


Lesenswert?

Sieht schon gut aus. Ich würde es aber abschließend noch in ein schönes 
Gehäuse packen.

Für mein 555 Wettbewerbsbeitrag habe ich z.B. mal per Heissluftstation 
versucht, Plexiglas zu biegen, was recht gut ging, wie in dem Video 
unten auf der Webseite von mir zu sehen:

http://www.frank-buss.de/555/index.html

Noch besser geht es mit Widerstandsdraht aus einem alten Fön und einem 
Aluminiumprofil:

http://www.youtube.com/watch?v=WQGoKUVfe6g

Aber nicht an die Steckdose anschließen, wäre auch viel zu heiss. Wie 
Jeri im Video sagt, an einem regelbaren Netzteil betreiben.

von Peter (Gast)


Lesenswert?

Ja, das Gehäuse kommt mit Sicherheit :-). Ich dachte da an irgendwas mit 
edlem Holz bzw. Holzfurnier. Vor einigen Jahren habe ich mal einen Tisch 
(nach-)gebaut. Als Füße habe ich massive Erle-Blöcke genommen. Sowas in 
der Art könnte ich mir vorstellen. Was bei Furnier halt echt auch total 
schick aussieht ist, wenn man das "spiegelt" - zB.:

http://www.pearlaudiovideo.com/products/speakers-products/bookshelf/dynaudio-focus-140/

BTW.: Das Video zu Deinem Wettbewerbsbeitrag ist echt gelungen. Bei dem 
Equipment schlägt mein Herz höher :-) Hab nicht mal ne "helfende Hand" 
beim Löten.

von Peter P. (uncle-sam7)


Lesenswert?

So, jetzt wäre das Display mit Menü auch mal soweit fertig 
durchgestyled:

http://www.youtube.com/watch?v=6Rh_4KHwc14

Menüführung funktioniert soweit. Beide Taster gleichzeitig als "Enter" 
lässt sich auch gut bedienen.

Die Balken rechts oben werden noch mit den 3 Stimmen des SID 
"verbunden"...

MfG
Peter

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
Noch kein Account? Hier anmelden.