energia 484 Posted April 8, 2014 Author Share Posted April 8, 2014 The only way to know if there is a XTAL present is to try and start it and check the fault flag. The 32kHz XTAL, according to the datasheet, can take 1 sec to startup for some MSP430's. I still have a question outstanding with the MSP430 folks to confirm this. Hence this is the reason it tries for 2 sec. I could give the user a define that they can set in the Sketch to indicate that there is no XTAL present and that would allow the code to skip over the XTAL testing all together. Quote Link to post Share on other sites
spirilis 1,264 Posted April 8, 2014 Share Posted April 8, 2014 Quick idea/solution for "interrupting" the sleep in the middle from an attachInterrupt() ISR: 1. wiring.c change: while(sleeping && (millis() - start <= seconds * 1000)) /* Wait for WDT interrupt in LPM3 */ __bis_status_register(LPM3_bits+GIE); as the conditional in both functions 2. WInterrupts.c change: __attribute__((interrupt(PORT1_VECTOR))) void Port_1(void) { uint8_t i, is_sleeping = sleeping; for(i = 0; i < 8; i++) { if((P1IFG & BV(i)) && intFuncP1[i]) { intFuncP1[i](); if(intChangeVectP1 & BV(i)) { P1IES ^= BV(i); P1IFG = ((P1IN & BV(i)) == (P1IES & BV(i))) ? \ (P1IFG & ~BV(i)) : P1IFG; } else { P1IFG &= ~BV(i); } } } if (sleeping != is_sleeping) __bic_SR_register_on_exit(LPM3_bits); } Just added the "sleeping" check... similar change was added for PORT2_VECTOR too. 3. Energia.h support: void delay(uint32_t milliseconds); void sleep(uint32_t milliseconds); void sleepSeconds(uint32_t seconds); extern volatile uint8_t sleeping; #define sleepAbort() { sleeping = false; } Just exposed the "sleeping" variable and sleepAbort() sets it to false. Example sketch that can be interrupted on the MSP430G2 launchpad with the P1.3 pushbutton: void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(PUSH2, INPUT_PULLUP); while (digitalRead(PUSH2)) delay(50); // wait for user press before writing anything to UART due to linux ACM bug Serial.println("Begin:"); attachInterrupt(PUSH2, myISR, FALLING); } void loop() { // put your main code here, to run repeatedly: Serial.print("millis: "); Serial.println(millis()); Serial.flush(); sleepSeconds(1); } void myISR() { sleepAbort(); } I'd say that "sleepAbort()" should be at the very end of the ISR simply to ensure the WDT ISR increments millis/micros correctly, since it tests that "sleeping" variable to determine how far to increment them. Output: Begin: millis: 517 millis: 1901 millis: 3278 millis: 4655 millis: 4667 millis: 4680 millis: 4692 millis: 4704 millis: 4716 millis: 4729 millis: 4741 millis: 6118 millis: 7495 millis: 8872 millis: 10249 millis: 11626 millis: 11640 millis: 11653 millis: 11666 millis: 11680 millis: 11693 millis: 11706 millis: 13084 millis: 14462 millis: 15840 (note all the rapid-fire short increments around 11626-11706, 4655-4741 where I pressed the button) Quote Link to post Share on other sites
p2baron 11 Posted May 19, 2014 Share Posted May 19, 2014 I am currently working on a low power mailbox sensor which notifies me when I recieve (snail) mail and when it is picked up. (I live in an appartment and my mailbox is in the central staircase) I've implement the changes from both Robert and Spirillis to enable low-power interrupts. This is the code: #include <x10rf.h> //https://github.com/p2baron/x10rf #define intpin1 P1_2 // Sensor on the outer lid <- used by mailman to deliver mail #define intpin2 P1_3 // Sensor on the inner lid <- used by me to pickup mail #define txpin P2_7 // Signal pin for 433Mhz module #define txvcc P2_6 // VCC oun for the 433Mhz module #define reps 4 // Number of times the RF message should be send. x10rf myx10 = x10rf(txpin,0,reps); void setup() { for(uint8_t i;i<20;i++) pinMode(i, INPUT_PULLDOWN); // Put all Pins in INPUT_PULLDOWN (see http://forum.43oh.com/topic/4984-low-power-mode-first-sketch/) myx10.begin(); pinMode(intpin1,INPUT_PULLUP); pinMode(intpin2,INPUT_PULLUP); pinMode(txvcc,OUTPUT); digitalWrite(intpin1, HIGH); digitalWrite(txvcc, LOW); attachInterrupt(intpin1, igotmail, CHANGE); attachInterrupt(intpin2, pickedupmail, CHANGE); } void loop() { sleepSeconds(200); } void igotmail() { uint8_t _state = digitalRead(intpin1); digitalWrite(txvcc, HIGH); if (_state == 0) { myx10.x10Security(3,0x04); // Send status alarm } sleep(10); digitalWrite(txvcc, LOW); sleepAbort(); } void pickedupmail() { uint8_t _state = digitalRead(intpin2); digitalWrite(txvcc, HIGH); if (_state == 0) { myx10.x10Security(3,0x84); // Send status normal } sleep(10); digitalWrite(txvcc, LOW); sleepAbort(); } My question is: Do I need to sleep in the main loop? And can I use "sleep" in the interrupt routines? Quote Link to post Share on other sites
spirilis 1,264 Posted May 19, 2014 Share Posted May 19, 2014 Never use it in an interrupt. Prefer to do the heavy lifting in the main loop(), and I'm not even sure that delay() would work either (?) in the interrupts... p2baron 1 Quote Link to post Share on other sites
maelli01 74 Posted May 19, 2014 Share Posted May 19, 2014 very nice! did some measurements, on a naked G2553, 3.5V supply, film cap as decoupling: sleep(200) 10uA sleep(2000) 0.5uA, same as sleepSeconds impressive! did I miss something, does the sleep function go into lower power mode for longer times? Quote Link to post Share on other sites
spirilis 1,264 Posted May 19, 2014 Share Posted May 19, 2014 very nice! did some measurements, on a naked G2553, 3.5V supply, film cap as decoupling: sleep(200) 10uA sleep(2000) 0.5uA, same as sleepSeconds impressive! did I miss something, does the sleep function go into lower power mode for longer times? I think sleepSeconds() is what goes into LPM for longer times. sleep() in theory uses more power b/c it has to wake up & check more often. Quote Link to post Share on other sites
p2baron 11 Posted May 19, 2014 Share Posted May 19, 2014 @@spirilis thanks. I will handle that in the main loop, I basically want to stay in LPM3/4 mode all of the time except when an interrupt occurs. Do I need to have sleepsecond(xxx) in the main loop? spirilis 1 Quote Link to post Share on other sites
spirilis 1,264 Posted May 19, 2014 Share Posted May 19, 2014 @@spirilis thanks. I will handle that in the main loop, I basically want to stay in LPM3/4 mode all of the time except when an interrupt occurs. Do I need to have sleepsecond(xxx) in the main loop? Yep. p2baron 1 Quote Link to post Share on other sites
energia 484 Posted May 21, 2014 Author Share Posted May 21, 2014 @@p2baron you brought up a good point and it made me think of extending the sleep API's with a sleep that takes no parameters. This function will put the MSP430 to sleep indefinitely. You would do an attachInterrupt() to the pin you want to wakeup from and exit sleep in your attachInterrupt() callback. What do you think? Would this work? Robert Quote Link to post Share on other sites
energia 484 Posted May 21, 2014 Author Share Posted May 21, 2014 I just realized that @@spirilis already offers a solution for the "sleep until interrupt" in one of the posts below. @@spirilis, do you have a pull request that we can review and then pull in? Quote Link to post Share on other sites
spirilis 1,264 Posted May 21, 2014 Share Posted May 21, 2014 I just realized that @@spirilis already offers a solution for the "sleep until interrupt" in one of the posts below. @@spirilis, do you have a pull request that we can review and then pull in? I'll roll one together today! Quote Link to post Share on other sites
energia 484 Posted May 21, 2014 Author Share Posted May 21, 2014 Awesome, thanks! Quote Link to post Share on other sites
spirilis 1,264 Posted May 21, 2014 Share Posted May 21, 2014 Awesome, thanks! And done- https://github.com/energia/Energia/pull/384 bluehash 1 Quote Link to post Share on other sites
manhdan 1 Posted June 16, 2014 Share Posted June 16, 2014 I use example in OneWire DS18B20 Library (code size is 4204 byte), it working very well: But when i replace Energia.h and wiring.c (new code size is 4342 byte), it doesn't working, is it not compatible? . Quote Link to post Share on other sites
energia 484 Posted June 17, 2014 Author Share Posted June 17, 2014 @@manhdan are you using any of the sleep functions? Have you tried a simple blinky and serial Sketch to make sure that the basic things still work? Robert Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.