MSP430 LPM4, UART wakeup, crashing...

Hi all, I'm currently working in an application that requires the MCU to g into deep sleep (LPM4) and wake up and process data on UART receive, an then go back to LPM4. What is the right way to do this? I tried doing th following as TI's guide Rev. E. suggests, but this crashes the MCU. tried to debug the code but I just can't find where the problem is. Th serial data is received using IR, in a constant stream that does not sto until the "transmitter" is taken away from the receiver. This will wor fine for a while but it eventually crashes.

What I've seen is that somehow when the software is busy handling a interrupt, it STILL accepts other interrupts even when the GIE bit is off Sometimes the instruction that sends the MCU back to active mode doesn't d anything or messes everything up. I really need help here as I'm runnin out of ideas. BTW, the problem is not on hardware, all of the require pins are correctly terminated to either VCC or ground, even th programming pins, reset, etc.

#include "msp430x12x.h" ;_______________________________________________________________________ ; INTERRUPT VECTORS USED ;_______________________________________________________________________ ORG 0FFFEh ; power-up interrupt DW RESET

ORG 0FFEEh ; USART0 receive interrupt DW RECEIVE

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; CODE ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ORG 0F000h ; program start for MSP430F122 ;___________________________ ; Reset Interrupt sequence ;___________________________ RESET MOV.W #0300h, SP ; initialize stack pointer CALL #INIT ; initalize the UART

MAIN BIS #LPM4+GIE, SR ; wait for start-edge NOP ; Needed by debugger CMP.B #f0, r8 ; check received data JNZ MAIN ; incorrect data! jmp! XOR.B #1, P1OUT ; toggle LED pin to ack received flag JMP MAIN

;_______________________________________________________________________ ; USART Interrupt sequence ;_______________________________________________________________________ RECEIVE BIT.B #URXIFG0,&IFG2 ; Test URXIFGx to determine JNZ StartRec ; If start-edge or character ; if IFG is set, Z=0, continue. ; if IFG not set (no complet transmission), return!

StartEdge ; wake up and receive char BIC.B #URXSE,&U0TCTL ; Clear URXS signal BIS.B #URXSE,&U0TCTL ; Re-enable edge detect BIC #SCG0+SCG1,0(SP) ; Enable BRCLK = DCO; CPU still off JMP EndRcv

StartRec MOV.B &U0RXBUF, r8 ; Save received char in r8 BIC #OE+FE+PE+RXERR,U0RCTL ;Clear any errors received BIC #LPM4+GIE,0(SP) ; Char received, wake up and proces data

EndRcv RETI

;_______________________________________________________________________ ; Initialization function (sets up UART, flags and interrupts) ;_______________________________________________________________________ INIT MOV.W #WDTPW+WDTHOLD, &WDTCTL ; stop watchdog BIS #OSCOFF, SR ; not using LFXTL1

//Initialize UART BIS.B #CHAR, &U0CTL ; 1 stop bit ; 8-bit word BIS.B #SSEL1, &U0TCTL ; use sub-main clock for UART (@750kHz) MOV.B #RATIO, &U0BR0 ; f = 750kHz in MSP430F122 MOV.B #000h, &U0BR1 ; MOV.B #00h, &U0MCTL ; receive moodulation set to zero; 0.0 is small BIS.B #URXSE, &U0TCTL ; enable start-edge wake-up BIS.B #020h, &P3SEL ; select P3.5 for serial reception BIC.B #020h, &P3DIR ; and input BIS.B #URXE0, &ME2 ; enable receiver (MSP430F122) BIC.B #SWRST, &U0CTL ; clear UART software reset BIS.B #URXIE0, &IE2 ; enable receiver interrupt (MSP430F122)

BIS.B #003h, &P1DIR ; P1.1 and P1.0 output BIS.B #003h, &P1OUT ; turn LEDs off

EINT ; enable interrupts: GIE This message was sent using the web interface on

formatting link

Reply to
jerry_bp
Loading thread data ...

IIRC, the LPM4 mode shuts off all the clocks, including that to the UART. Are you sure that the UART clock is starting up quickly enough to capture the start bit?

If the data is really received in a constant stream, you might be better off not going into LPM4 mode after each character---but only when no character has been received for a pre-determined interval.

Mark Borgerson

Reply to
Mark Borgerson

Mark is right. Been there, done that.

When you sleep in LPM4, there is only one way to get out of it: you can use an interrupt from any peripheral that *doesn't* use a clock. All clocks are off in LPM4.

Waking from LPM4 is slow because it takes some time for the clocks to restart. If you're app demands single clock cycle response on wakeup, then LPM3 might be a better choice for sleeping.

They call LMP4 "done mode". Please take that tag literally. You're app woll be done doing whatever it's doing if it's in LPM4. LPM is called "sleep mode". Your app will be active but waiting to wakeup (IOW, not done).

There is a useful table in the User' Guide that shows which clocks are on and off for the various LPMs.

JJS

enough

Reply to
johnspeth

Just some thoughts:

- Does your code work properly while not going LPM or going to another LPM?

- You turn it on inside the interrupt routine. Don't do it, the CPU will turn it on while executing RETI.

You don't properly switch the CPU to inactive mode - you don't use CPUOFF bit.

GIE is already 1 before this instruction.

Needed only if there is nothing after it - it's not your case.

Why do you turn interrupts off here?

Actually it's an output here.

Reply to
Grzegorz Mazur

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.