Hallo,
vor einigen Tagen fragte hier jemand nach einer soften I²C
Implementierung, ich glaube für den ATtiny13. Damals konnte ich kein
Beispiel geben, aber jetzt habe ich eins, weil ich es gerade für eine
Bastelei selber brauchte.
Der ATtiny13 hat weder ein TWI noch ein USI Interface,
deswegen kann man das Protokoll nur "zu Fuß" per Bit-Banging
implementieren. Der Quelltext ist trivial und daher sicher leicht auf
andere Mikrocontroller portierbar.
Viel Spaß damit
Hi
>Der ATtiny13 hat weder ein TWI noch ein USI Interface,>deswegen kann man das Protokoll nur "zu Fuß" per Bit-Banging>implementieren. Der Quelltext ist trivial und daher sicher leicht auf>andere Mikrocontroller portierbar.
Gibt es als AppNote von ATMEL seit 1997.
MfG Spess
Stefanus,
Als Verständnis-Basis ganz brauchbar und auch hinreichend dokumentiert.
Zu einer kompletten Lösung fehlt aber noch einiges,
- Slaveseitiges Clockstretching handelst Du m.E. nicht/nicht optimal.
- Und komplett fehlt ein Exeption/ErrorHandling:
Wenn hier der Slave abkackt, hängt auch der Master forever!
Prof. Lösungen machen masterseitig ein Timeout und versuchen zumindest,
den Bus wieder freizutakten, teils mehrmals nach zugebilligter
Erholungsphase. Falls das fehlschlägt gibt es zumindest ein
ErrorHandling und der Master "überlebt".
Ich nehme aber an, dass Stefanus den Code eher als "Basis" verstanden
haben will.
Persönlich setze ich solche BIOS-Dinge grundsätzlich in Assembler um,
das steigert Performance/schrumpft Code um Faktoren! Von solchen
elementaren BIOS-Aufgaben sollten Hochsprachen besser die Finger lassen.
@SPESS:
> Gibt es als AppNote von ATMEL seit 1997.
Ja, stimmt.
Die dortige Umsetzung ist aber nur akademisch/rudimentär, hat mit realer
Anforderung fast-nix zu tun und taugt nicht für die Praxis.
Interessant wäre mal eine TAUGLICHE SLAVE-LÖSUNG für TINYs ohne USI, das
ist nämlich ungleich herausfordender, wenn man einigermassen
praxistauglich sein möchte.
In eben-dieser-Praxis sind TINYs auch eher als SLAVE zu vermuten, als
als Master.
Hi
>Ja, stimmt.>Die dortige Umsetzung ist aber nur akademisch/rudimentär, hat mit realer>Anforderung fast-nix zu tun und taugt nicht für die Praxis.
Blödsinn. Ist in Geräten unserer Firma schon mehrere 1000 mal verkauft
wurden. Und das nennst du 'taugt nicht für die Praxis.'
Dann solltest du an mal deiner Praxis feilen.
Jim Beam ist ubrigens ein grauenhaftes Gesöff. Amis können keins Whiskey
machen.
MfG Spess
@SPESS:
1000x unprofessionell bleibt unprofessionell, wird durch Multiplikation
nicht besser...
Mehr von dem Unsinn, den Du schriebst kommentiere ich nicht.
Aber wie Du selbst durchblicken lässt:
> Amis können keins Whiskey machen.
DEIN Problem scheint wirklich der Alkohol zu sein... ;-)
Jim Beam schrieb:> Ich nehme aber an, dass Stefanus den Code eher als "Basis" verstanden> haben will.
Genau. Beim Errorhandling käme ja auch gleich die Frage auf, was denn im
Fehlerfall passieren soll. Eine generische Lösung, die dann auch noch
mit den minimalen Ressourcen des ATtiny13 angemessen sparsam umgeht,
kann ich mir nicht vorstellen.
An das Clock-Stretching habe ich gar nicht gedacht. Danke für den
Hinweis.
> Interessant wäre mal eine TAUGLICHE SLAVE-LÖSUNG für TINYs ohne USI,> das ist nämlich ungleich herausfordender
Allerdings. Darauf habe ich ehrlich gesagt keine Lust. Es ist ja nicht
so, dass man unbedingt auf Teufel komm raus den kleinsten µC ohne die
dafür vorgesehene Hardware verwenden muss.
> In eben-dieser-Praxis sind TINYs auch eher als SLAVE zu vermuten,> als als Master.
Jawohl, aber dann bitte wenigstens einen mit USI.
Jim Beam schrieb:> Persönlich setze ich solche BIOS-Dinge grundsätzlich in Assembler um,> das steigert Performance/schrumpft Code um Faktoren!
Es steigert nichts, da auch in Assembler die 100kHz abgewartet werden
müssen.
Und der Code wird bestenfalls minimal kleiner (micro-optimisation).
Jim Beam schrieb:> - Slaveseitiges Clockstretching handelst Du m.E. nicht/nicht optimal.
Braucht man aber nur, wenn der I2C-Slave ein MC ist. Bei dummen
I2C-Slaves ist SCL nur ein Eingang (PCF8574, DS1307, MCP3425, 24C512
usw.).
Hier noch ne I2C-Lib:
Beitrag "Re: I2C Eeprom AT24C512 Lib für Pagewrite in C"
Hallo,
Peter D. schrieb:> Braucht man aber nur, wenn der I2C-Slave ein MC ist. Bei dummen> I2C-Slaves ist SCL nur ein Eingang (PCF8574, DS1307, MCP3425, 24C512> usw.).
die Grenze kann sehr fließend sein. Komplexe ICs, die per I2C
gesteuert/programmiert werden, nutzen es durchaus. Das Datenblatt weißt
normalerweise nicht darauf hin, weil es zum I2C-Standard gehört.
Vor vielen Jahren hat mich ein MP3-Decoder (MAS3507) damit zur
Verzweiflung gebracht.
Gruß aus Berlin
Michael
Michael U. schrieb:> Das Datenblatt weißt> normalerweise nicht darauf hin
Steht aber drin, Seite 34: I2CC SCL IN/OUT
Bei den oben genannten ICs fehlt beim SCL-Pin das "OUT".
Außerdem steht drin, daß der MAS3507 ein DSP mit ROM ist, also kein
"dummes" Hardware-I2C.
Ist aber auch kein großer Akt, bei solchen Slaves ein Warten auf SCL_in
= 1 zu ergänzen.
wenn ich so etwas sehe ... bäh, klippschule?!
... byte = (byte << 1) & 0xFF;
mt
hier mal zwei varianten für die "high performer" ...
void i2c_send(uint8_t data) { //send data bits and starts with msb
for (uint8_t bit = 0; bit!=8; bit++) {
if (data & (0x80>>bit)) SDA_HIGH;
else SDA_LOW;
I2C_DELAY;
SCL_HIGH;
I2C_DELAY;
SCL_LOW;
}
}
oder so ...
void i2c_send(uint8_t data) { //send data bits and starts with msb
uint8_t bitChanges = data ^ (data>>1);
for (uint8_t bit = 0x80; bit; bit >>= 1) {
//toggling, if not avr DATA_PIN ^= 1;
if (bitChanges & bit) PINB = 1<<DATA_PIN;
I2C_DELAY;
SCL_HIGH;
I2C_DELAY;
SCL_LOW;
}
}
Apollo M. schrieb:> ... byte = (byte << 1) & 0xFF;
Den Teil "& 0xFF" kürzt der Compiler raus, der steht da nur, um Lint
zufrieden zu stellen. Übrig bleibt eine Simple LSL Operation. Erzähle
mir nicht, dass die unperformant sei.
Bist du ganz sicher, dass "(0x80>>bit)" schneller ist?
Ich finde deinen Ansatz auch nicht so gut. die Bits von 0 bis 7 zu
zählen, aber tatsächlich die Bits 7 bis 0 zu senden. Das stiftet
Verwirrung.
Außerdem Hand auf Herz: Kommt es bei I²C auf einzelne CPU Takte an?
Stefanus F. schrieb:> Übrig bleibt eine Simple LSL Operation
Ich habe jetzt mal ins Assembler Listing geschaut. Interessanterweise
hater Compiler daraus "add r24, r24" gemacht. Aber egal, ist auch nur
eine kurze Operation mit dem gleichen Ergebnis.
Anbei die korrigierte Datei mit Clock-Stretching.
Hi
>Interessanterweise>hater Compiler daraus "add r24, r24" gemacht. Aber egal, ist auch nur>eine kurze Operation mit dem gleichen Ergebnis.
lsl r24 und add r24,r24 haben den gleichen Assemblercode. Also ist
beides richtig.
MfG Spess
Stefanus F. schrieb:> Bist du ganz sicher, dass "(0x80>>bit)" schneller ist?>> Ich finde deinen Ansatz auch nicht so gut. die Bits von 0 bis 7 zu> zählen, aber tatsächlich die Bits 7 bis 0 zu senden. Das stiftet> Verwirrung.
die beste variante ist die nr.2, welche auch geeignet ist um eine
schnelle sw spi variante zu bauen!
diese benutzt den avr toggle befehl, welcher dann auch für die clock
benutzt werden sollte! nur wenn ein bit sich ändert wird toggling
active, darum auch schneller!
uint8_t bitChanges = data ^ (data>>1);
for (uint8_t bit = 0x80; bit; bit >>= 1) {
//toggling, if not avr DATA_PIN ^= 1;
if (bitChanges & bit) PINB = 1<<DATA_PIN;
@verwirrung, das argument finde ich "gut" - näh lieber doch nicht, weil
das kommt immer öfter, wenn mal der definierte sprachumfang von c auch
benutzt wird.
mt
Apollo M. schrieb:> diese benutzt den avr toggle befehl, welcher dann auch für die clock> benutzt werden sollte!
MOMENT MAL....
Du setzt doch NICHT ETWA bei H das Portbit auf AUSGANG-H??
Das enspricht absolut NICHT der I2C-Spec.!
Korrekt ist:
H = Port-ist-EINGANG mit Pullup
L = Port-ist-AUSGANG mit elektrisch L
Ansonsten kann es elektrische Kurzschlüsse auf dem Bus geben,
und es widerspricht komplett der I2C-Spezifikation.
Das wird ständig und gerne falsch gemacht.
... ich liebe kurzschlüsse, am besten wenn's dann so richtig gut nach
geschmorten riecht!
mein beispiel kommt von meiner sw spi ...
du hast recht mit dem hinweis zu i2c, daher sollte dann das dddrx reg
zum toggling benutzt werden!
wichtig wäre hier zu erkennen, dass das toggling prinzip key ist!
mt
Apollo M. schrieb:> die beste variante ist die nr.2
Warum? Schneller ist hier vollkommen sinnlos, da die gesparte Zeit in
einer längeren Warteschleife vernichtet werden muss.
Ich lege in erster Linie Wert auf gut lesbaren Code, da ich in einem
Team arbeite und oft Sachen korrigieren muss, den Kollegen vorher
entwickelt haben. Oft ist das so alter Code, dass sich niemand mehr
daran erinnern kann und daher auch nicht erklären kann.
Performance-Optimierung steht in der Rangliste ganz unten, noch unter
Keller-Aufräumen.
Jim Beam schrieb:> Stefanus,>> Als Verständnis-Basis ganz brauchbar und auch hinreichend dokumentiert.> Zu einer kompletten Lösung fehlt aber noch einiges,>> - Slaveseitiges Clockstretching handelst Du m.E. nicht/nicht optimal.> - Und komplett fehlt ein Exeption/ErrorHandling:> Wenn hier der Slave abkackt, hängt auch der Master forever!>> Prof. Lösungen machen masterseitig ein Timeout und versuchen zumindest,> den Bus wieder freizutakten, teils mehrmals nach zugebilligter> Erholungsphase. Falls das fehlschlägt gibt es zumindest ein> ErrorHandling und der Master "überlebt".> Ich nehme aber an, dass Stefanus den Code eher als "Basis" verstanden> haben will.
Für den Beitrag hast Du Dir einen großen Schluck Laphroaig verdient!
Speziell der Hinweis mit dem Freitakten ist wichtig, wenn es darum geht
zuverlässige I2C-Lösungen zu bauen.
> Persönlich setze ich solche BIOS-Dinge grundsätzlich in Assembler um,> das steigert Performance/schrumpft Code um Faktoren! Von solchen> elementaren BIOS-Aufgaben sollten Hochsprachen besser die Finger lassen.
Auf einem Tiny13 macht Assembler nicht nur Spaß, sondern auch Sinn. Ist
halt noch ein niedlich kleiner Mikrocontroller. Und so ein Bitbongo (tm)
ist in Assembler auch nicht schlechter zu lesen als in C.
Für morgen Vormittag habe mir eine Portierung inkl. Sensoransteuerung
für einen Soft-I2C in Maschinensprache auf einen ATtiny814 vorgenommen.
Der Baustein kommt in einem Gerät als Hausmeister zum Einsatz. Die ganze
Baugruppe nimmt im Sleep, mit laufendem WDT, unter Normalbedingungen
gemessene <2µA auf.
Stefanus F. schrieb:> Warum? Schneller ist hier vollkommen sinnlos, da die gesparte Zeit in> einer längeren Warteschleife vernichtet werden muss.
Das scheint nur so. Tatsächlich kann man gesparte Takte in in der
Bitschieberei und Ausgabe dafür nutzen, das nächste Byte zu holen (als
Transmitter) bzw. das vorige zu verarbeiten (als Receiver). Das
verbessert insgesamt zumindest den Durchsatz oder erlaubt es überhaupt
erst, bestimmte Timing Constraints einzuhalten.
Das gilt nicht nur für I2C, sondern ganz generell für alle Sachen die
irgendwelche Bitserialierungen machen. Bekanntes Beispiel für sowas ist
z.B. V-USB. Das würde ohne solche Techniken überhaupt nicht
funktionieren können.
Der Trick ist dabei eben gerade, die "überflüssige" Zeit nicht in
nutzlosen Warteoperationen zu vernichten, sondern sie sinnvoll zu
nutzen.
> Ich lege in erster Linie Wert auf gut lesbaren Code
Wenn ich die Wahl habe zwischen schlecht lesbarem Code und gut lesbaren,
aber komplett unbrauchbarem Code, dann fällt mir diese Wahl nicht
schwer...
Aber OK, für einen I2C-Master spielt das alles wirklich nur eine
untergeordnete Rolle. Wenn er richtig implementiert ist, wird auch
langsamer Code immer funktionieren. Nur der erreichbare Durchsatz ist
halt nicht so hoch, wie er sein könnte. Wenn er trotzdem genügt: ja dann
würde ich natürlich auch den gut lesbaren Code bevorzugen. Schon
deshalb, weil er auch viel einfacher zu schreiben ist...
Marcus H. schrieb:> Für morgen Vormittag habe mir eine Portierung inkl. Sensoransteuerung> für einen Soft-I2C in Maschinensprache auf einen ATtiny814 vorgenommen.
Warum? Der hat doch ein richtiges TWI Interface sogar mit Filter für
"noise and spike suppression" und konfigurierbaren Timeouts.
Mein obiger Code kann doch nur eine Notlösung mit provisorischem
Charakter sein.
Stefanus F. schrieb:> Marcus H. schrieb:>> Für morgen Vormittag habe mir eine Portierung inkl. Sensoransteuerung>> für einen Soft-I2C in Maschinensprache auf einen ATtiny814 vorgenommen.>> Warum? Der hat doch ein richtiges TWI Interface sogar mit Filter für> "noise and spike suppression" und konfigurierbaren Timeouts.
Weil ich
- eine Menge Erfahrung mit undokumentierten Features in I2C Interfaces
verschiedenster MCUs und Peripheriebausteine habe
- den ATtiny814 erstmals einsetze
- weil in dieser Anwendung ein Software-Automat, der auf zig Maschinen
läuft, das geringste Risiko darstellt und am einfachsten zu
dokumentieren ist
- weil meine Anwendungen nicht nur mal eben kurz auf dem Schreibtisch
laufen sollen, sondern ohne Wartungsmöglichkeit für lange Zeit im Feld
unterwegs sind
> Mein obiger Code kann doch nur eine Notlösung mit provisorischem> Charakter sein.
Die Anfänger die sich auf Deinen Post verlassen wären sicher froh
gewesen, Du hättest diese Einschätzung Deines Beispiels auch eingangs
schon so geschrieben.
Marcus H. schrieb:> Die Anfänger die sich auf Deinen Post verlassen wären sicher froh> gewesen, Du hättest diese Einschätzung Deines Beispiels auch eingangs> schon so geschrieben.
Ja stimmt, darauf hätte ich hinweisen sollen.
Aber auf einem µC mit nur 32 Bytes RAM (+32 Register) kann man halt
ohnehin keine Weltbewegenden Sachen machen. Ich habe den nur verwendet,
weil ich meine Vorräte aufbrauchen will.
Stefanus F. schrieb:> aber jetzt habe ich eins, weil ich es gerade für eine> Bastelei selber brauchte
Ist ja soweit OK, nur ein paar Bemerkungen meinerseits:
- i2c_start sollte bool sein und die while Zeile in i2c_start sollte
durch eine kleine Verzögerung und dann ggf. return false ergeben.
- in i2c_stop sollte die while Zeile ganz raus. Es ist ja bereits alles
erledigt.
- das unbegrenzte while in i2c_send ist auch nicht nett.
- das i2c_communicate mißfällt mir. Es ist mir zu überladen. Ich mache
es lieber getrennt, das ist mMn handlicher:
void I2C_Init (void);
bool Do_I2C_Start (byte Adresse, bool obRead); // 7 bit
bool Do_I2C_Write (byte aByte);
byte Do_I2C_Read (bool Acknowledge);
void Do_I2C_Stop (void);
W.S.
Hi
>Auf einem Tiny13 macht Assembler nicht nur Spaß, sondern auch Sinn. Ist>halt noch ein niedlich kleiner Mikrocontroller. Und so ein Bitbongo (tm)>ist in Assembler auch nicht schlechter zu lesen als in C.
Gibt es doch schon: AVR300: Software I2C™ Master Interface
MfG Spess
Apollo M. schrieb:> hier mal zwei varianten für die "high performer" ...>> void i2c_send(uint8_t data) { //send data bits and starts with msb> for (uint8_t bit = 0; bit!=8; bit++) {> if (data & (0x80>>bit)) SDA_HIGH;> else SDA_LOW;>> I2C_DELAY;> SCL_HIGH;> I2C_DELAY;> SCL_LOW;> }> }>> oder so ...
Das ist für dich high performer. aha.
Ähem.. guck mal:
1
byteI2C_dio(byteb)
2
{bytec,e;
3
c=0x80;
4
e=0;
5
while(c)
6
{if(b&c)SDA_high();elseSDA_low();
7
sdelay(sdavorscl);
8
SCL_high();
9
sdelay(sclhigh);
10
c=c>>1;
11
e=e<<1;
12
if(SDA_State())e|=1;
13
SCL_low();
14
sdelay(sdahalte);
15
}
16
returne;
17
}
Das kann man sowohl für Read als auch für Write benutzen. Bei Read eben
$FF senden. Allerdings schert es sich nicht um Verzögerungen vom Slave.
W.S.
Stefanus F. schrieb:> Aber auf einem µC mit nur 32 Bytes RAM (+32 Register) kann man halt> ohnehin keine Weltbewegenden Sachen machen. Ich habe den nur verwendet,> weil ich meine Vorräte aufbrauchen will.
Der Tiny13 hat allerdings 64Byte RAM (+32 Register)...
Ich gebe dir allerdings trotzdem insofern Recht, dass der Tiny13 ein
wirklich ziemlich eingeschränkter Vertreter der AVR8-Familie ist. Ich
bin zu meinem einzigen Exemplar vor ca. 10 Jahren gekommen, als er die
paar Cent beigetragen hat, die ich noch brauchte, um bei einer
Pollin-Bestellung einen Gutschein einlösen zu können.
In all den Jahren war er bei etlichen Projekten immer mal wieder in der
Vorauswahl, ist dann aber immer wegen irgendwelcher störenden
Beschränkungen rausgeflogen. So kommt es, dass ich dieses eine Exemplar
dieser Supergurke immer noch rumliegen habe. Inzwischen bin ich auch
nicht mehr sicher, dass ich überhaupt jemals eine passende Anwendung für
das Teil finde. Für Anwendungen der in Frage kommenden Klassen ist immer
der Tiny25 die bessere Wahl und der kostet ja praktisch dasselbe.
Der Tiny13 hat aber ein besonderes Feature, was bisher nicht erwähnt
wurde:
Nämlich der RC-Clock mit 9.6Mhz anstelle 8Mhz der anderen 8-Pinner.
Kann manchmal nützlich sein.
Jim Beam schrieb:> Der Tiny13 hat aber ein besonderes Feature, was bisher nicht erwähnt> wurde:> Nämlich der RC-Clock mit 9.6Mhz anstelle 8Mhz der anderen 8-Pinner.
Die anderen kannst du per OSCCAL auch völlig problemlos auf 9.6
zwirbeln. Ist dann zwar, streng genommen, ausserhalb der jeweiligen
Specs, aber mir ist noch kein Fall untergekommen, wo diese moderate
"Übertaktung" (sowieso nur relevant für den Schreibzugriff auf Flash und
EEPROM) irgendwie zu Problemen geführt hätte. Garantiert ist es aber
herstellerseitig eben nicht. Das kann schon wichtig sein. Für
Bastelprojekte allerdings nicht und auch nicht für kommerzielle
Anwendungen, wo eben nicht in Flash oder EEPROM geschrieben wird.
c-hater schrieb:> Die anderen kannst du per OSCCAL auch völlig problemlos auf 9.6> zwirbeln.
Interessant, käme mir sehr gelegen wenn das klappt.
Werde das auf jeden Fall mal pröben.
Habe mal irgendwann bei Atmel gelesen, dass man OSCCAL nur in kleinen
Schritten ändern sollte, von 8->9.6 wäre dann aber schon ein Klopper
nehme ich an. Sollte ich da am Progstart eine Schleife einbauen, oder
wie hast Du das gemacht?
> - weil meine Anwendungen nicht nur mal eben kurz auf dem Schreibtisch> laufen sollen, sondern ohne Wartungsmöglichkeit für lange Zeit im Feld> unterwegs sind
In dem Falle ist I2C grundsaetzlich nicht verwendbar. Es gibt naemlich
durchaus ICs die sich so weghaengen das sie die Clockleitung auf Masse
ziehen. Deshalb gibt es modernere I2C-ICs die einen Mindesttakt
verlangen und sich resetten.
Olaf
Jim Beam schrieb:> Sollte ich da am Progstart eine Schleife einbauen, oder> wie hast Du das gemacht?
Ganz einfach:
OSCCAL = 0xff;
Dann läuft das Teil mit ca. 14 - 15 MHz. Ein 20 MHz AVR wird damit auch
nicht übertaktet.
Fertig.
Lieber Olaf (Gast):
seufz Ich finde solche pauschalen Ansagen immer recht schwierig. Im
Endeffekt hast Du geschrieben, dass Du die Kompetenz des von Dir
zitierten Schreibers anzweifelst. Gleichzeitig ist das Zitat aus dem
Zusammenhang gerissen.
Für Dich sicherer wäre in diesem Fall eine Formulierung wie "I2C ist
bekanntermaßen sehr störanfällig. Wie gehst Du mit diesem Problem um?"
Zumal der Schreiber bereits signalisiert hatte, dass ihm allerlei
Probleme bekannt sind.
Also, schauen wir uns Deinen Post mal im Detail an:
Olaf schrieb:>> - weil meine Anwendungen nicht nur mal eben kurz auf dem Schreibtisch>> laufen sollen, sondern ohne Wartungsmöglichkeit für lange Zeit im Feld>> unterwegs sind>> In dem Falle ist I2C grundsaetzlich nicht verwendbar. Es gibt naemlich> durchaus ICs die sich so weghaengen das sie die Clockleitung auf Masse> ziehen.
Es gibt Master und Slave Engines die sich so weghängen, dass sie nur mit
einem Powercycle wieder zu beleben sind. Ein Grund, warum I2C ein von
mir nicht sehr geschätztes Interface ist. Allerdings gibt es manchmal
Sachzwänge, wenn z.B. ein Sensorhersteller nur dieses Interface zur
Verfügung stellt.
>Deshalb gibt es modernere I2C-ICs die einen Mindesttakt> verlangen und sich resetten.>> Olaf
Nach Deiner o.G. Aussage bin ich mir nicht sicher, was der Wert dieser
Info ist? Sind diese I2C nun tauglich oder nicht?
Also was machen wir nun? Wir bekommen wir die Kuh vom Eis? Wie würdest
Du mit diesen Problemen umgehen?
Ein kurze Liste an Vorschlägen, ohne Anspruch auf Vollständigkeit:
- die Slaves können vom Master freigeclockt werden
- wenn das nicht hilft kann der Master einen Powercycle der Slaves
auslösen
- wenn ein Powercycle des Masters aufgrund einer hängenden I2C Engine
nicht erwünscht ist, ist die Firmwareimplementation ein überschaubares
Risiko
- es gibt Watchdog Konzepte nicht nur für MCUs sondern auch für
Gesamtsysteme. Für ganz bestimmte Fälle kann man aber auch im
Batteriemanagement einen Powercycle des Komplettsystems anstoßen
Als erstes sollte man klären, ob diese ganzen Maßnahmen überhaupt
angemessen sind.
In meinem konkreten Fall geht es um ein Kinderspielzeug (ein
Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.
Alfred K. schrieb:> Ganz einfach:> OSCCAL = 0xff;
Wie Jim Beam schon festgestellt hat, empfiehlt Atmel, bei Änderungen von
OSCCAL keine großen Sprünge zu machen. Sie sollten <= 2% bleiben. Also
besser in einer Schleife vom Initialwert zum gewünschten Wert laufen
lassen.
> Dann läuft das Teil mit ca. 14 - 15 MHz. Ein 20 MHz AVR wird damit auch> nicht übertaktet.
Darum geht es auch garnicht. Worum es geht, sind Schreibvorgänge in
Flash oder EEPROM. Das dafür nötige Timing wird bei den allermeisten
AVR8 aus dem RC-Oszillator abgeleitet, auch die Programmierspannung
wird mit Ladungspumpen erzeugt, die durch diesen Oszillator getaktet
werden.
DA sind also ggf. Probleme zu erwarten, nicht beim Betrieb der MCU. Die
MCU macht erst Probleme, wenn der Takt für die Betriebsspannung zu hoch
wird, bei 5V und RC-Oszillator als Taktquelle also nie, auch nicht wenn
man OSCCAL auf Maximum setzt. Bei kleineren Betriebsspannungen sieht das
naturgemäß anders aus, dann muss man natürlich auch diese Abhängigkeit
bei Spielereien an OSCCAL berücksichtigen.
Das steht übrigens alles in den Datenblättern, man muss die einfach nur
mal lesen...
Olaf schrieb:
...
> In dem Falle ist I2C grundsaetzlich nicht verwendbar. Es gibt naemlich> durchaus ICs die sich so weghaengen das sie die Clockleitung auf Masse> ziehen. Deshalb gibt es modernere I2C-ICs die einen Mindesttakt> verlangen und sich resetten.
Weil ich das gestern bei meinem aktuellen Thema gesehen habe:
In die Richtung geht auch der Soft Reset bei den Sensirion SDP3x -
Command 0x0006: Datenblatt "Soft Reset"
"This sequence resets the sensor with a separate reset block,
which is as much as possible detached from the rest of the
system on chip. Note that the I 2 C address is 0x00, which is the
general call address, and that the command is 8 bit. The reset is
implemented according to the I2C specification."
Einziger Haken ist die Situation in der ein Device dauerhaft eine
Busleitung nach unten zieht - dann bekommt man den Bus auf diese Weise
nicht mehr unter Kontrolle. Handelt es sich um SDA, dann probiert man zu
Toggeln, bis SDA wieder auf High geht. Wenn es sich um ein "verlängertes
Clock Stretching" handelt, braucht man einen Plan B.
Stefanus F. schrieb:> Als erstes sollte man klären, ob diese ganzen Maßnahmen überhaupt> angemessen sind.
Wichtig ist vor allem das Bewusstsein, dass der ganze Kram nicht
unfehlbar ist. Nicht dass sich hier irgendwann einer vor lauter Frust
hinter einen Zug wirft.
> In meinem konkreten Fall geht es um ein Kinderspielzeug (ein> Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.
Mmmh? Ich hatte Dich älter eingeschätzt. :D
c-hater schrieb:> Worum es geht, sind Schreibvorgänge in> Flash oder EEPROM. Das dafür nötige Timing wird bei den allermeisten> AVR8 aus dem RC-Oszillator abgeleitet
Damit hast Du Recht und das muß berücksichtigt werden, wenn man
schreibende EEPROM-Zugriffe braucht. Da das Timing eh sehr ungenau sein
wird, kann man bei Bedarf OSCCAL auch vor und nach den Zugriffen
umstellen.
c-hater schrieb:> Das steht übrigens alles in den Datenblättern, man muss die einfach nur> mal lesen...
Da steht aber auch, dass man während der Änderungen den Prozessor im
Reset halten soll. Dazu hätte ich gerne ein Programmbeispiel.
Geht man zu den ATmega, dann gibt es keine Einschränkungen, die nur 2%
Änderungen empfehlen. In der Praxis funktioniert auch direktes
Beschreiben mit 0xFF problemlos.
Das zu den AVR Datenblättern.
Ich sehe jedenfalls keinen Grund, einen ATtiny13 nur wegen seiner 9,6
MHz einem ATtiny25/45/85 zu bevorzugen.
Marcus H. schrieb:>> In meinem konkreten Fall geht es um ein Kinderspielzeug (ein>> Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.> Mmmh? Ich hatte Dich älter eingeschätzt. :D
Ich bin der, der nicht rein darf.
Alfred K. schrieb:> Da das Timing eh sehr ungenau sein> wird, kann man bei Bedarf OSCCAL auch vor und nach den Zugriffen> umstellen.
Jepp.
> Da steht aber auch, dass man während der Änderungen den Prozessor im> Reset halten soll.
Das bezieht sich auf einen extern eingespeisten Takt und genau den
"verbotenen" Fall. Sprich: wenn man das macht, muss man das per externer
Hardware lösen, eine Lösung per Programm ist dann natürlich nicht
möglich.
Bezüglich des RC-Oszillators hilft eine Tatsache, die nicht dokumentiert
ist, sich aber sehr leicht nachweisen läßt. Nämlich der Fakt, dass die
Änderung von dessen Takt per OSCCAL einer Zeitkonstante unterliegt. Der
erzeugte Takt folgt also nicht sprunghaft dem Wert in OSCCAL. Deswegen
bleibt in den meisten Fällen auch eine größere Änderung von OSCCAL
folgenlos. Wenn man sich die Sprungantwort anschaut, sieht man aber,
dass bei wirklich extremen Änderungen die 2%-Latte sehr deutlich
gerissen wird. Wenn man also clever ist, vermeidet man diese potentiell
gefährliche Situation, zumal die "Kosten" dafür ja nun wirklich sehr
überschaubar sind.
> Ich sehe jedenfalls keinen Grund, einen ATtiny13 nur wegen seiner 9,6> MHz einem ATtiny25/45/85 zu bevorzugen.
Sag' ich ja. Die potentiellen Probleme lassen sich halt mit sehr wenig
Aufwand zuverlässig umgehen, wenn sie denn in einer konkreten Anwendung
überhaupt relevant sind.
Stefanus F. schrieb:> Marcus H. schrieb:>>> In meinem konkreten Fall geht es um ein Kinderspielzeug (ein>>> Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.>> Mmmh? Ich hatte Dich älter eingeschätzt. :D>> Ich bin der, der nicht rein darf.
You made my day! :)
Das ist ja, wie wenn man bei der NSA "Verschlüsselungssoftware" kaufte.