So, ich habe jetzt ein wenig mit dem Code gespielt.
Das Delay bringt keine Verbesserung - hätte ich da auch nicht wirklich erwartet.
Was gegen das (langsame) digitalRead() spricht (außer Stromverbrauch), weiß ich auch nicht.
Ich deute das wie folgt:
Code: Alles auswählen
void setup () {
DINIT(57600,ASKSIN_PLUS_PLUS_IDENTIFIER); // initialisiert den Debug UART
pinMode(ACTIVATE_PIN, OUTPUT); // Selbthaltung...
digitalWrite(ACTIVATE_PIN, HIGH); // ...aktiv
pinMode(CC1101_PWR_PIN, OUTPUT); // Funkmodul...
digitalWrite(CC1101_PWR_PIN, LOW); // ...ein
pwrOffAlarm.init(); // irgendwas mit Batterie und Abschaltung...
dann kommt das:
Code: Alles auswählen
buttonISR(cfgBtn,CONFIG_BTN); // initialisiert den Portpin und schalter den Pegelwechsel-Interrupt auf dem Portpin scharf
remoteISR(sdev,1,BTN01_PIN); // initialisiert den Portpin und schalter den Pegelwechsel-Interrupt auf dem Portpin scharf
remoteISR(sdev,2,BTN02_PIN); // initialisiert den Portpin und schalter den Pegelwechsel-Interrupt auf dem Portpin scharf]
D.h. JETZT sind doch im Hintergrund schon die Interrupts scharf und werden ggf. sofort gestartet, weil die Taste ja gedrückt ist.
Und das sdev ist noch gar nicht initialisiert und die hal.battery auch nicht. Oder übersehe ich da was?
Dann werden die Ports (gemütlich) zu Fuß abgefragt:
Code: Alles auswählen
uint8_t TA = 0;
if (digitalRead(CONFIG_BTN) == LOW) TA = 1;
if (digitalRead(BTN01_PIN) == LOW) TA = 2;
if (digitalRead(BTN02_PIN) == LOW) TA = 3;
DPRINT("TA = ");DDECLN(TA);
und nur, wenn hier ein Tastendruck erkannt wird, wird der ganze Init Kram aufgerufen:
Code: Alles auswählen
if (TA>0) {
sdev.init(hal);
hal.battery.init();
hal.battery.low(BAT_LOW);
hal.battery.critical(BAT_CRIT);
sdev.initDone();
while (hal.battery.current() == 0);
if (hal.battery.critical()) pwrOffAlarm.powerOff(false);
StorageConfig sc = sdev.getConfigArea();
uint8_t msgCount = sc.getByte(MSG_COUNT_BYTE);
while (sdev.nextcount() < msgCount);
hal.radio.setSendTimeout();
if (TA == 1) cfgBtn.irq();
else if (TA == 2) sdev.channel(1).button().irq();
else if (TA == 3) sdev.channel(2).button().irq();
} else {
pwrOffAlarm.powerOff(false);
}
Über TA wird dann ggf. die Tastenpin Interrupt Routine zu Fuß angestoßen. Kann es sein, dass das mal so klappt und die anderen Male die ISR direkt nach der Initialisierung direkt startet ohne das das sdev.init und Co. durchläuft?
Das
lässt den µC direkt wieder abschalten, oder was bewirkt das?
Habe das ganze mal so geändert:
Code: Alles auswählen
void setup () {
DINIT(57600,ASKSIN_PLUS_PLUS_IDENTIFIER); // initialisiert den Debug UART
pinMode(ACTIVATE_PIN, OUTPUT); // Selbthaltung...
digitalWrite(ACTIVATE_PIN, HIGH); // ...aktiv
pinMode(CC1101_PWR_PIN, OUTPUT); // Funkmodul...
digitalWrite(CC1101_PWR_PIN, LOW); // ...ein
pwrOffAlarm.init(); // irgendwas mit Batterie und Abschaltung...
//uint8_t TA = 0;
//if (digitalRead(CONFIG_BTN) == LOW) TA = 1;
//if (digitalRead(BTN01_PIN) == LOW) TA = 2;
//if (digitalRead(BTN02_PIN) == LOW) TA = 3;
//DPRINT("TA = ");DDECLN(TA);
if (1) { // IMMER!!! Eine Taste muss ja gedrückt sei, wenn er aufwacht...
sdev.init(hal);
hal.battery.init();
hal.battery.low(BAT_LOW);
hal.battery.critical(BAT_CRIT);
sdev.initDone();
while (hal.battery.current() == 0);
if (hal.battery.critical()) pwrOffAlarm.powerOff(false);
StorageConfig sc = sdev.getConfigArea();
uint8_t msgCount = sc.getByte(MSG_COUNT_BYTE);
while (sdev.nextcount() < msgCount);
hal.radio.setSendTimeout();
//if (TA == 1) cfgBtn.irq();
//else if (TA == 2) sdev.channel(1).button().irq();
//else if (TA == 3) sdev.channel(2).button().irq();
buttonISR(cfgBtn,CONFIG_BTN); // initialisiert den Portpin und schalter den Pegelwechsel-Interrupt auf dem Portpin scharf
remoteISR(sdev,1,BTN01_PIN); // initialisiert den Portpin und schalter den Pegelwechsel-Interrupt auf dem Portpin scharf
remoteISR(sdev,2,BTN02_PIN); // initialisiert den Portpin und schalter den Pegelwechsel-Interrupt auf dem Portpin scharf
} else {
pwrOffAlarm.powerOff(false);
}
}
Funktioniert aber auch nicht besser...
Weil ich die Lib nicht überblicke und da nur an der Oberfläche rumkratze.
Ich hätte jetzt erwartet, das das sdev.init durch sein muss, bevor ein Pinwechsel Interrupt aufgerufen werden darf.
Die button.isr scheint ein Objekt per sysclock.add in eine Abarbeitungsliste außerhalb der ISR zuzufügen.
Wo und wie das ganze abgearbeitet wird, finde ich aber nicht... Daher kann ich auch nicht schauen, ob das ggf. geblockt wird, wenn das sdev nocht initialisiert ist.
Eventuell ist mein Erwartungsmodell aber auch falsch... Ich weiß es nicht.