PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : MCP2515 ignoriert direkt nach Reset Befehle über SPI



HuskyNET
17.06.2008, 22:43
Hallo,

ich möchte mit einem ATmega48 einen MCP2515 ansteuern. Wenn ich (bei 16 MHz Takt beider ICs) erst über SPI einen Reset ausführe, dann 150 ns warte und dann einen Wert in ein Register schreibe, so wird dieser Wert korrekt gespeichert. Wenn ich zwischen Reset und Registerzugriff weniger als 100 ns warte, wird der Wert nicht gespeichert.

Woran könnte das liegen? Die SPI-Verbindung an sich funktioniert ja, gesendet werden beide Befehle auf auf jeden Fall (ich verändere ja nur die Wartezeit zwischen dem Senden beider Befehle).

Grüße
Randy

pongi
18.06.2008, 07:44
Ich weiss zwar nicht, was ein MCP2515 ist, es ist aber bei meist allen ICs so, dass sie eine gewisse Anlaufzeit nach einem Reset haben. Wahrscheinlich sinds bei dem halt 150ns.

McJenso
18.06.2008, 08:49
Hallo,

du meinst 150 ms, ja?
Ich frage nach dem Reset das SPIF auf dem SPSR ab. Danach startet sofort das Bittiming. SPI läuft mit fosc/2 auch @ 16Mhz. Wenn du in C schreibst zeig doch mal den Code.

Gruß

Jens

HuskyNET
18.06.2008, 10:18
Ähm ich meinte eigentlich rund 10 Nanosekunden, also 150 nop-Befehle, hatte das verwechselt. SPI läuft auch bei mir mit fosc/2.

@pongi: MCP2515 ist ein externer CAN-Controller. Das mit der Anlaufzeit klingt zwar einleuchtend, aber ich habe bisher noch nirgends einen Beispielcode gesehen, der wirklich zwischen Reset und dem Konfigurieren der Register eine Zeit lang wartet. Im Datenblatt kann ich dazu auch nichts finden.

Mein Code:


// Enable SPI, Master, set clock rate fck/2 -> 8 MHz
SPCR = (1<<SPE) | (1<<MSTR);
SPSR = (1<<SPI2X);

mcp2515_reset();
mcp2515_write(BFPCTRL, (1<<B0BFS) | (1<<B0BFE)); // Enable LED at RX0BF-Pin


uint8_t spi_putc(uint8_t data)
{
SPDR = data;
while (!(SPSR & (1<<SPIF))) ;
return SPDR;
}

void mcp2515_reset()
{
PORTB &= ~(0b00000100); // Chip Select low

spi_putc(0xC0);

PORTB |= 0b00000100; // Chip Select high
}

void mcp2515_write(uint8_t address, uint8_t data)
{
PORTB &= ~(0b00000100); // Chip Select low

spi_putc(0x02);
spi_putc(address);
spi_putc(data);

PORTB |= 0b00000100; // Chip Select high
}

Wenn ich den Code so ausführe geht die LED nicht an (auch wenn ich in ein anderes Register schreibe und das Register wieder auslese, wurde der Wert darin nicht gespeichert). Aber wenn ich zwischen dem Reset und dem Write eben die 150 nop-Befehle warte, DANN funktioniert der Code.

Vitis
18.06.2008, 12:18
doch, ist so, hab ich bei Testaufbau auch beobachtet, das der MCP
erst "bootet" bevor er Anweisungen entgegennimmt ... don't worry
be happy

steht aber auch irgendwo im DB versteckt

McJenso
18.06.2008, 14:41
Hallo,

definitiv funktioniert bei mir das schreiben der Register unmittelbar nach dem Reset. Der Code sieht auf den ersten Blick gut aus. Denoch, was ich nicht weiß ist, wie schnell man nach Anlegen der Versorgung warten muss. Sollte sich aber schnell herausfinden lassen, indem du die NOP's mal vor den Reset schreibst. Ich starte meine Controller immer mit der größten Wartezeit und es werden vor dem CAN noch andere Initialisierungen durchgeführt.
Falls sich bis morgen Abend keine Lösung gefunden hat, will ich gerne bei mir das ganze mal näher testen. Ist auch für mich sehr interessant, da ich diesen Baustein mehrfach einsetzen möchte.

Gruß

Jens

HuskyNET
18.06.2008, 20:02
Da ist über ISP programmiere ist bei mir die Versorgungsspannung die ganze Zeit ein, aber auch wenn ich vor dem Reset 3 Sekunden warte, geht die LED nicht an, wenn ich sie direkt nach dem Reset einschalte.

Ich habe den MCP2515 auch schon testweise durch einen anderen getauscht, mit dem gleichen Ergebnis. Wenn du sagst, bei dir funktioniert das direkt nach dem Reset, muss ich mir das morgen nochmal genau angucken. Sowohl die Schaltung (naja, viel kann man da ja nicht falsch machen - im Prinzip gehts ja), als auch den Code, also dass ich mal alles überflüssige davor und danach rauslösche und die einzelnen Funktionen direkt in die main() einbette.

McJenso
20.06.2008, 10:09
Hallo,

so, mein Test hat ergeben, dass Vitis recht hat. Ich habe die Stelle im Datenblatt zwar nicht gefunden, konnte aber feststellen, dass man wirklich einen Moment warten muss, bis man in die Register schreiben kann. Dies ist bei mir nie aufgefallen, da ich bisher keinen anderen Busteilnehmer als die MCP2515 getestet habe. Das erste Register für das Timing wurde bei keinem der Controller geschrieben. Ich habe den Bus mit einer viel zu großen Baudrate betrieben. In den bisherigen Testaufbauten hat das funktioniert und ist nie aufgefallen.

Wirklich ärgerlich wäre das in den nächsten Tage für mich geworden. Im Moment baue ich eine Platine mit einem AT90CAN128 auf. Die Kommunikation mit dem MCP hätte wohl nicht geklappt. Den Fehler hätte ich wohl Tagelang beim AT90 vermutet.

Gruß

Jens

HuskyNET
20.06.2008, 15:33
Ok, auch gut, dann ist es bei mir wenigstens kein Fehler im Code sondern eine Eigenheit des MCP2515. Sollte man halt nur wissen... Also vielen Dank nochmal!


Wirklich ärgerlich wäre das in den nächsten Tage für mich geworden. Im Moment baue ich eine Platine mit einem AT90CAN128 auf. Die Kommunikation mit dem MCP hätte wohl nicht geklappt. Den Fehler hätte ich wohl Tagelang beim AT90 vermutet.

Freut mich, anderen geholfen zu haben O:) ;-)

Grüße
Randy

PS: Und noch was zu meinen 10 Nanosekunden...es sind natürlich 10 Mikrosekunden... Gestern ist mir aufgefallen, dass zwischen Milli und Nano doch noch Mikro kommt *ääähm :cheesy:

ba4_philipp
21.06.2008, 09:01
Senf: Genau das Problem hat mich auch schon etliche Stunden gekostet mit dem MCP2515 :)

Hat jmd nun mal die Stelle im Datenblatt gefunden, die angibt wielange man nach dem Reset nun wirklich warten muss?

Gruß Philipp

McJenso
21.06.2008, 10:05
Hallo,

im Datenblatt habe ich bisher nur diesen Hinweis gefunden.



The MCP2515 utilizes an oscillator startup timer (OST)
that holds the MCP2515 in reset to insure that the
oscillator has stabilized before the internal state
machine begins to operate. The OST maintains reset
for the first 128 OSC1 clock cycles after power-up or
wake up from sleep mode occurs. It should be noted
that no SPI operations should be attempted until after
the OST has expired.

Wobei ich das eigentlich nicht auf einen Reset via SPI beziehen würde.
Weil während der OST der Baustein ja im Reset gehalten wird. :-s
Mit den 150 NOP's passt das dann aber sehr schön.

Gruß

Jens

ba4_philipp
21.06.2008, 10:43
Meine Probleme bestanden aber auch nach nur einem einfachen SPI Reset und die Betriebsspannung lag vorher schon lange an, wie hier auch schon von anderen geschildert wurde.
Bei einigen scheint es wohl zufällig so zu stimmen, dass es keine Probleme gibt. Hab das vor einiger Zeit auch mal im Mikrocontroller Forum gefragt und da kam auch nicht wirklich was dabei raus. Bis ich beim debuggen mittels UART gemerkt hab, dass es mit delays keine Probleme gibt. Vorher hatte ich auch immer falsche Datenraten usw, was dazu führte, dass einige Module sich unterhalten konnten und andere wieder nicht. (Bin froh, dass ich nun nicht mehr allein damit bin :) )

Gruß Philipp