This is probably just the usual issue with debounce of a switch
(attaching the battery is a switch), and the system getting caught out.
Typically you would have an INIT process shortly after start up with a
clock stabilisation loop or similar. I don't know how you handle NMI's
but typically if your NMI handling is too simplistic you will get a
clock error, jump to the NMI which might then get stuck in a loop or
stall, or simply corrupt the PC. If you have a LED try having the LED
flash briefly during INIT, ie on very fast then off once stable. Then
have it turned fully on in the NMNI and point the NMI back to itself.
That will tell you if this is the issue.
Al
On 22/10/2013 4:50 PM, Peter Grey wrote:
> I have been using these chips for a while. My devices
have a battery
> connected to them and, in some cases a battery charger. I find that
> when I first connect a battery or take it off a charger it will not
> work. I need to push a reset button. I have tried a reset chip and it
> makes no difference. I can tell a customer to always press reset after
> the above events but I want to find out what is going on and fix it.
> Has anyone experienced any such behaviour.
>
> TIA
>
> Peter
Problems with MSP430F2132
Started by ●October 22, 2013
Reply by ●October 22, 20132013-10-22
Hi Al,
Thanks for the detailed reply. I must admit I have not used NMI since I was
using the PDP mini's, and that is a while ago! I shall take a look and may
have a few questions
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 22 October 2013 4:26 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
This is probably just the usual issue with debounce of a switch (attaching
the battery is a switch), and the system getting caught out. Typically you
would have an INIT process shortly after start up with a clock stabilisation
loop or similar. I don't know how you handle NMI's but typically if your NMI
handling is too simplistic you will get a clock error, jump to the NMI which
might then get stuck in a loop or stall, or simply corrupt the PC. If you
have a LED try having the LED flash briefly during INIT, ie on very fast
then off once stable. Then have it turned fully on in the NMNI and point the
NMI back to itself. That will tell you if this is the issue.
Al
On 22/10/2013 4:50 PM, Peter Grey wrote:
I have been using these chips for a while. My devices have a battery
connected to them and, in some cases a battery charger. I find that when I
first connect a battery or take it off a charger it will not work. I need to
push a reset button. I have tried a reset chip and it makes no difference. I
can tell a customer to always press reset after the above events but I want
to find out what is going on and fix it. Has anyone experienced any such
behaviour.
TIA
Peter
Thanks for the detailed reply. I must admit I have not used NMI since I was
using the PDP mini's, and that is a while ago! I shall take a look and may
have a few questions
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 22 October 2013 4:26 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
This is probably just the usual issue with debounce of a switch (attaching
the battery is a switch), and the system getting caught out. Typically you
would have an INIT process shortly after start up with a clock stabilisation
loop or similar. I don't know how you handle NMI's but typically if your NMI
handling is too simplistic you will get a clock error, jump to the NMI which
might then get stuck in a loop or stall, or simply corrupt the PC. If you
have a LED try having the LED flash briefly during INIT, ie on very fast
then off once stable. Then have it turned fully on in the NMNI and point the
NMI back to itself. That will tell you if this is the issue.
Al
On 22/10/2013 4:50 PM, Peter Grey wrote:
I have been using these chips for a while. My devices have a battery
connected to them and, in some cases a battery charger. I find that when I
first connect a battery or take it off a charger it will not work. I need to
push a reset button. I have tried a reset chip and it makes no difference. I
can tell a customer to always press reset after the above events but I want
to find out what is going on and fix it. Has anyone experienced any such
behaviour.
TIA
Peter
Reply by ●October 23, 20132013-10-23
The NMI rest vector is shared with the /RST and also with several other
faults like the Flash violation and clock oscillator failure.
Al
On 23/10/2013 12:02 PM, Peter Grey wrote:
> Hi Al,
>
> Thanks for the detailed reply. I must admit I have not used NMI since
> I was using the PDP mini's, and that is a while ago! I shall take a
> look and may have a few questions
>
> Thanks
>
> Peter
>
> *From:*m... [mailto:m...] *On
> Behalf Of *Onestone
> *Sent:* Tuesday, 22 October 2013 4:26 PM
> *To:* m...
> *Subject:* Re: [msp430] Problems with MSP430F2132
>
> This is probably just the usual issue with debounce of a switch
> (attaching the battery is a switch), and the system getting caught
> out. Typically you would have an INIT process shortly after start up
> with a clock stabilisation loop or similar. I don't know how you
> handle NMI's but typically if your NMI handling is too simplistic you
> will get a clock error, jump to the NMI which might then get stuck in
> a loop or stall, or simply corrupt the PC. If you have a LED try
> having the LED flash briefly during INIT, ie on very fast then off
> once stable. Then have it turned fully on in the NMNI and point the
> NMI back to itself. That will tell you if this is the issue.
>
> Al
>
> On 22/10/2013 4:50 PM, Peter Grey wrote:
>
> I have been using these chips for a while. My devices have a
> battery connected to them and, in some cases a battery charger. I
> find that when I first connect a battery or take it off a charger
> it will not work. I need to push a reset button. I have tried a
> reset chip and it makes no difference. I can tell a customer to
> always press reset after the above events but I want to find out
> what is going on and fix it. Has anyone experienced any such
> behaviour.
>
> TIA
>
> Peter
faults like the Flash violation and clock oscillator failure.
Al
On 23/10/2013 12:02 PM, Peter Grey wrote:
> Hi Al,
>
> Thanks for the detailed reply. I must admit I have not used NMI since
> I was using the PDP mini's, and that is a while ago! I shall take a
> look and may have a few questions
>
> Thanks
>
> Peter
>
> *From:*m... [mailto:m...] *On
> Behalf Of *Onestone
> *Sent:* Tuesday, 22 October 2013 4:26 PM
> *To:* m...
> *Subject:* Re: [msp430] Problems with MSP430F2132
>
> This is probably just the usual issue with debounce of a switch
> (attaching the battery is a switch), and the system getting caught
> out. Typically you would have an INIT process shortly after start up
> with a clock stabilisation loop or similar. I don't know how you
> handle NMI's but typically if your NMI handling is too simplistic you
> will get a clock error, jump to the NMI which might then get stuck in
> a loop or stall, or simply corrupt the PC. If you have a LED try
> having the LED flash briefly during INIT, ie on very fast then off
> once stable. Then have it turned fully on in the NMNI and point the
> NMI back to itself. That will tell you if this is the issue.
>
> Al
>
> On 22/10/2013 4:50 PM, Peter Grey wrote:
>
> I have been using these chips for a while. My devices have a
> battery connected to them and, in some cases a battery charger. I
> find that when I first connect a battery or take it off a charger
> it will not work. I need to push a reset button. I have tried a
> reset chip and it makes no difference. I can tell a customer to
> always press reset after the above events but I want to find out
> what is going on and fix it. Has anyone experienced any such
> behaviour.
>
> TIA
>
> Peter
Reply by ●October 23, 20132013-10-23
Here is my assembler layout for a typical MSP430F449 chip:
The first section of the program is the declanation of Interrupt Vector (IV)
Depending on what chip, you will have 2, 4, 8 IV. The 449 chip has 2 IV
and the address from FFE0 to FFFE (the last two by is POWER ON RESET) that I
named PWRON and I called DOZE (address FFFC for the Oscillator, NMI reset).
I called MAIN address FFFA for the timer_B compare 0: with Timer B we will
have 7 of them from 0,1,2,3,4,5,6). I use here for example only 1 compare
interrupt Timer B_0 . And I named BINTR for Port 1 address FFE8.
;********************** INTERRUPT VECTORS
***********************************
RSEG INTVEC ;
DW TRAPE0 ;$FFE0.......................
.N/U
DW TRAPE2 ;$FFE2.......................
.N/U
DW TRAPE4 ;$FFE4.......................
.N/U
DW TRAPE6 ;$FFE6.......................
.N/U
DW BINTR ;$FFE8....I/O PORT P1
DW TRAPEA ;$FFEA........................
N/U
DW TRAPEC ;$FFEC.......................
.N/U
DW TRAPEE ;$FFEE.......................
.N/U
DW TRAPF0 ;$FFF0....UART0 XMIT
DW TRAPF2 ;$FFF2....UART0 RCVE
DW TRAPF4 ;$FFF4....WATCHDOG TIMER
DW TRAPF6 ;$FFF6......................
..N/U
DW TRAPF8 ;$FFF8....TIMER_B (CAP/COMP
1/6, OVRFLOW)
DW MAIN ;$FFFA....TIMER_B
(COMPARE0)
DW DOZE ;$FFFC....OSC FAULT, NMI
DW PWRON ;$FFFE....POWER UP RESET
;********************** INITIAL RESET
***************************************
;
RSEG CODE
;----
------------------
PWRON: DINT
;DISABLE GENERAL INTERRUPTS
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE
WATCHDOG TIMER,
CLR.B &P1IE
;DISABLE P1 INTERRUPTS
MOV.W #SFE(CSTACK),SP
;START OF STACK
PWR0A: BIT.B #LFOF,&FLL_CTL0
;LOOP WHILE LF FAULT
JNZ PWR0A
BIT.B #DCOF,&FLL_CTL0
;LOOP WHILE DCO FAULT
JNZ PWR0A
;----
----------------
As you can see, the chip will start the CODE at PWRON as the battery
inserted, the comments for each line of code is good enough for explanation
isn't it? SO the chip will stablize after 2 loops to check for LF fault and
DCO fault. After that you can initialize all the ports, clear all the RAM
memory, ... Do wahtever you have to do to initially, setup the program, and
finally, branch to ENDAY: put the chip to sleep mode for storage, save the
power.
Suppose I have only 1 button for the device port 1.0. I need to enable the
button interrupt for port 1.0
;-------------- code for ENDAY --------------------------
ENDAY: CLR.B &P1IFG
; CLR POSSIBLE INTERRUPT FLAGS
BIC.B #01H,&P1DIR
; MAKE P1.0 INPUT
MOV.B #01H,&P1IES
; INTERUPT EDGE...P1.0 HI TO LO
MOV.B #01H,&P1IE
; ENBL P1.0 INTERRUPT
MOV.W #SFE(CSTACK),SP
; START OF STACK (CLEAR)
MOV.W #SCG1+SCG0+CPUOFF+GIE,SR ;
LPMODE3..ENABLE GENERAL INTERRUPT and
NOP
; WHILE ASLEEP
; A SWITCH ACTIVATION WILL VECTOR
TO
; BINTR AND WILL RETI AFTER
ALTERING THE
; SR ON THE STACK, IF THE CONTACT
IS VALID.
; THE PROGRAM WILL CONTINUE FROM
HERE WITH A
; BRANCH TO `NEWDAY', WHICH WILL
CAUSE THE
; UNIT TO POWERUP. IF AN
INTERMITTENT
; CLOSURE, THE UNIT WILL SHUTDOWN
IN LOW
; POWER MODE AGAIN.
BIC #TBIE,&TB0CTL
; DISABLE TIMER B OVERFLOW INTERRUPT
BRA #NEWDAY
;. START THE PROGRAM WHEN THE BUTTON INTERRUPT
; TO TURN THE DEVICE ON.
;----
---------
Now the chip is sleep in LPM mode 3 to save power. When the button is
pressed:
;---------------- CODE TO CHECK FOR BUTTON INTERRUPT
----
BINTR: CLR.B &P1IFG
;CLEAR PORT 1 INTERRUPT FLAGS
BIS.W #GIE,SR
;RE-ENABLE GENERAL INTERRUPT
MOV.W #0400H,TEMP
;DELAY FOR 5 MS
BINT00: DEC.W TEMP
;16 BIT.W REGISTER..DECREMENT TILL 0000H
JNZ BINT00
MOV.B &P1IN,BTNSAV
;CHECK FOR SWITCH INTERRUPT (XITION TO LO)
INV.B BTNSAV
;CHANGE TO POSITIVE LOGIC
AND.B #01H,BTNSAV
;MASK FOR BIT 0
JZ BINT01
;FALSE INTERRUPT
TST.B OPMODE
;IF OPMODE = SLEEPMODE=0 THEN SET SR ON
; THE STACK TO POWERUP ON RTI
JNZ BINT02
; NOT SLEEP
;ASLEEP
BIC #TBIE,&TB0CTL
;DISABLE TIMER_B OVERFLOW INTERRUPTS
CLR 0(SP)
;SET CPU ACTIVE ON RTI
BINT01: RETI
BINT02: MOV.B BTNSAV,BTNMEM
;SAVE FOR BUTTON CHECK ROUTINE
RETI ; ..
;--------------- END OF BUTTON INTERRUPT
---------------------------------
As you can see the code to detect the bouncing button for 5 ms. if the
button is pressed < 5 ms then it will be ignored. An valid button pressed
will return and wake the CPU up and start the NEWDAY routine (in DOZE). It
will start your program (turn on your device). If it is not from the sleep
mode (OPMODE = 0 operation mode) then it will be OPMODE 1, 2,3, 4 whatever
you named it then you know what to do with the button pressed. Example,
OPMODE 1 is in SET HOUR, the button will increase the HOURS, if the OPMODE 2
is in SET MINUTE, the button pressed will increase MINUTES. And as you know
with port 1 we can have total 8 buttons to do so many thing.
Now for the DOZE, this is the place for the CPU to rest (LPM3) to save
power:
;----------- code for the DOZE
--------------
DOZE: MOV #SFE(CSTACK),SP
;START OF STACK (CLR POSSIBLE PENDING RTI)
BIC.B #01H,&P1DIR
; MAKE P1.0 INPUTS
MOV.B #01H,&P1IES
;INTERUPT EDGE...HI TO LO ON P1.0
MOV.B #01H,&P1IE
;ENABLE P1.0 INTERRUPTS
MOV #0120H,&TBCTL
;RECONDITION TIMERB 32KHZ, CONT UP..CAUTIONARY
ADD #1000H,&TBCCR0
;ADD 125MS TO COMPARE B0 REG (4096/32768)
MOV #0010H,&TBCCTL0
;ENABLE TIMERB COMPARE0 INTERRUPT
;-----------------------------------
DOZ00: MOV #00D8H,SR
;LPMODE3..ENABLE GENERAL INTERRUPT
NOP
;BTTN PRESSES WHILE IN DOZE WILL VECTOR TO
; BINTR AND ReTI BACK TO HERE TO THE LO
PWR mode
;125MS COMPARE WILL VECTOR TO MAIN.
;MAIN WILL TERMINATE WITH A BRANCH BACK
TO DOZE.
; IN ORDER TO SET UP THE SWITCH
INTERRUPTS
; AND ADD 125MS TO THE NEXT COMPARE
INTERRUPT.
JMP DOZ00
;PRECAUTION
;-------------- end code for doze
-----
-
As you see up to now, the program (the CPU) resets at PWRON, loop until the
CPU is stable then go to ENDAY to sleep to save power. If a button is
pressed during sleep mode, the RETI will trigger the SR to turn the CPU ON,
the program will go to NEWDAY:
;----------- code for the NEWDAY ----------------------------
NEWDAY:
.......... DO whatever you have to do to display the device or do something
then branch to DOZE to let the CPU sleep. During the CPU sleep in DOZE, the
timer B compare 0 with 125 ms (1000H will be 125 ms, 2000H will be 250 ms,
and so on ... depends on how many ms seconds you want the button to react.)
BR #DOZE
;--------- end code for NEWDAY ----------------------------
Now the code for the MAIN: the MAIN will be running every 125 ms during
awake mode and you can do different task in the MAIN depends on what you
want to do:
;---------------- Code for MAIN running every 125 ms during awake
-------------
MAIN: MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE WATCHDOG
TIMER,
INC.B EIGHTHS
;INCREMENT 1/8 SEC CTR
AND.B #07H,EIGHTHS
;MASK OFF UNUSED BITS
BIS.W #GIE,SR
;RE-ENABLE GEN INTERRUPTS FOR BTTN PRESSES
MOV.B EIGHTHS,R5
RLA R5
BR MAIN00(R5)
MAIN00: DW JOB0
DW JOB1
DW JOB2
DW JOB3
DW JOB4
DW JOB5
DW JOB6
DW JOB7
JOB0: Do something then ..
BR #DOZE
JOB1: Do something then ..
BR #DOZE
JOB2: Do something then ..
BR #DOZE
JOB3: Do something then ..
BR #DOZE
JOB4: Do something then ..
BR #DOZE
JOB5: Do something then ..
BR #DOZE
JOB6: Do something then ..
BR #DOZE
JOB7: Do something then ..
BR #DOZE
;-------------- end code for MAIN -------------------
This is a complete frame programming for a MSP430F449 chip from start power
up, detect LF and DCO fault to make sure 100% the CPU is stable and back to
sleep, wait for a button pressed to wake up and start a NEWDAY then go back
to sleep. During AWAKE mode, every 125 ms, the CPU will wake up to check
for any task that it has to do, then back to sleep until the program go back
to ENDAY (like 2 hours without a button pressed, the program will go back to
sleep mode.
Finally about TRAPE0, TRAPE2, ... I name it and put a code in it routine to
see if any interrupt occur during my program running so I can trap that
interrupt back to DOZE so I don't have any unwanted interrupt that will make
my program go haywired.
TRAPE0: MOV.B #0E0H,ERROR
... display the ERROR so I know what going all
.. delay the dislpay for 10 seconds ....
BR #DOZE
it is also a good programming when we put all the initialization in one
routine that I called PREP (prepare):
;------------ code to put all initialization in one routine ----------------
PREP: MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE
WATCHDOG TIMER,
MOV.B #032H,&SCFQCTL
;DCOCLK = 50*30.518 = 1.52mhz, MODULATION ON
CLR.B &SCFI0
;DCO RANGE = .65/6mhz
CLR.B &SCFI1
; ..
MOV.B #0B0H,FLL_CTL0
;SELECT.. DCO, LO FREQ, 10pf LOAD
MOV.B #020H,FLL_CTL1
;XT2OFF, ACLK/1
CLR.B &IE1
;CAUTIONARY DISABLE MODULE INTERRUPT
REGISTERS
CLR.B &IE2
CLR.B &IFG1
;CAUTIONARY CLEAR MODULE INTERRUPT FLAGS
CLR.B &IFG2
; ..
CLR.B &ME1
;CAUTIONARY MODULE DISABLES
CLR.B &ME2
; ..
;-------------- TIMER A SETUP
-----
----------
; SET UP TIMER A FOR SOME USE, LIKE A PIEZO TO MAKE A SOUND OR SOMETHING
;----
--------------
MOV #0104H,&TACTL
;TIMERA ACLK, STOPPED, CLEARED
MOV #0008H,&CCR0
;COMPARE REG0 TO 7(DELAYED), TACL0 4096hz
MOV #0004H,&CCR2
;COMPARE REG1 TO 4, TACL1 (50%DC)
MOV #00E0H,&CCTL2
;PREPARE OUTP UNIT1 FOR RESET/SET
CLR &CCTL0
;CLR CAP/COMP CONTROL REG0
BIC #0010H,&TACTL
;STOP 4KHZ PIEZO DRIVE
;------------ PORT1 ----------------
;P1.0 button
;P1.1 to P1.7 N/U
CLR.B &P1IES
;INTERUPT EDGE...LOW TO HI
CLR.B &P1OUT
;SET PORT1 OUTPUT LATCHES LOW
MOV.B #0FEH,&P1DIR
;ALL OUTPUT EXCEPT P1.0 is INPUT
CLR.B &P1IE
;DISABLE P1 INTERRUPTS
CLR.B &P1IFG
;RESET POSSIBLE INTERRUPT FLAG
CLR.B &P1SEL
;Make port 1 to be all IO line
;PORT2
;PORT3
;PORT4
;PORT5
;PORT6
CLR &ADC12CTL0
;CLEAR A/D CONTROL REGISTERS
CLR &ADC12CTL1 ; ..
CLR &ADC12IFG
;CLEAR INTERRUPT ENABLE FLAG REGS
CLR &ADC12IE ; ..
RET
;---------- end code for PREP -------
You can put the PREP right after the CPU is stable then clear RAM, read
EEPROM ... before put the CPU into sleep mode.
I hope to help you guy with some information that I worked in the field of
assembler for the MSP430.
Anthony Ha
The first section of the program is the declanation of Interrupt Vector (IV)
Depending on what chip, you will have 2, 4, 8 IV. The 449 chip has 2 IV
and the address from FFE0 to FFFE (the last two by is POWER ON RESET) that I
named PWRON and I called DOZE (address FFFC for the Oscillator, NMI reset).
I called MAIN address FFFA for the timer_B compare 0: with Timer B we will
have 7 of them from 0,1,2,3,4,5,6). I use here for example only 1 compare
interrupt Timer B_0 . And I named BINTR for Port 1 address FFE8.
;********************** INTERRUPT VECTORS
***********************************
RSEG INTVEC ;
DW TRAPE0 ;$FFE0.......................
.N/U
DW TRAPE2 ;$FFE2.......................
.N/U
DW TRAPE4 ;$FFE4.......................
.N/U
DW TRAPE6 ;$FFE6.......................
.N/U
DW BINTR ;$FFE8....I/O PORT P1
DW TRAPEA ;$FFEA........................
N/U
DW TRAPEC ;$FFEC.......................
.N/U
DW TRAPEE ;$FFEE.......................
.N/U
DW TRAPF0 ;$FFF0....UART0 XMIT
DW TRAPF2 ;$FFF2....UART0 RCVE
DW TRAPF4 ;$FFF4....WATCHDOG TIMER
DW TRAPF6 ;$FFF6......................
..N/U
DW TRAPF8 ;$FFF8....TIMER_B (CAP/COMP
1/6, OVRFLOW)
DW MAIN ;$FFFA....TIMER_B
(COMPARE0)
DW DOZE ;$FFFC....OSC FAULT, NMI
DW PWRON ;$FFFE....POWER UP RESET
;********************** INITIAL RESET
***************************************
;
RSEG CODE
;----
------------------
PWRON: DINT
;DISABLE GENERAL INTERRUPTS
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE
WATCHDOG TIMER,
CLR.B &P1IE
;DISABLE P1 INTERRUPTS
MOV.W #SFE(CSTACK),SP
;START OF STACK
PWR0A: BIT.B #LFOF,&FLL_CTL0
;LOOP WHILE LF FAULT
JNZ PWR0A
BIT.B #DCOF,&FLL_CTL0
;LOOP WHILE DCO FAULT
JNZ PWR0A
;----
----------------
As you can see, the chip will start the CODE at PWRON as the battery
inserted, the comments for each line of code is good enough for explanation
isn't it? SO the chip will stablize after 2 loops to check for LF fault and
DCO fault. After that you can initialize all the ports, clear all the RAM
memory, ... Do wahtever you have to do to initially, setup the program, and
finally, branch to ENDAY: put the chip to sleep mode for storage, save the
power.
Suppose I have only 1 button for the device port 1.0. I need to enable the
button interrupt for port 1.0
;-------------- code for ENDAY --------------------------
ENDAY: CLR.B &P1IFG
; CLR POSSIBLE INTERRUPT FLAGS
BIC.B #01H,&P1DIR
; MAKE P1.0 INPUT
MOV.B #01H,&P1IES
; INTERUPT EDGE...P1.0 HI TO LO
MOV.B #01H,&P1IE
; ENBL P1.0 INTERRUPT
MOV.W #SFE(CSTACK),SP
; START OF STACK (CLEAR)
MOV.W #SCG1+SCG0+CPUOFF+GIE,SR ;
LPMODE3..ENABLE GENERAL INTERRUPT and
NOP
; WHILE ASLEEP
; A SWITCH ACTIVATION WILL VECTOR
TO
; BINTR AND WILL RETI AFTER
ALTERING THE
; SR ON THE STACK, IF THE CONTACT
IS VALID.
; THE PROGRAM WILL CONTINUE FROM
HERE WITH A
; BRANCH TO `NEWDAY', WHICH WILL
CAUSE THE
; UNIT TO POWERUP. IF AN
INTERMITTENT
; CLOSURE, THE UNIT WILL SHUTDOWN
IN LOW
; POWER MODE AGAIN.
BIC #TBIE,&TB0CTL
; DISABLE TIMER B OVERFLOW INTERRUPT
BRA #NEWDAY
;. START THE PROGRAM WHEN THE BUTTON INTERRUPT
; TO TURN THE DEVICE ON.
;----
---------
Now the chip is sleep in LPM mode 3 to save power. When the button is
pressed:
;---------------- CODE TO CHECK FOR BUTTON INTERRUPT
----
BINTR: CLR.B &P1IFG
;CLEAR PORT 1 INTERRUPT FLAGS
BIS.W #GIE,SR
;RE-ENABLE GENERAL INTERRUPT
MOV.W #0400H,TEMP
;DELAY FOR 5 MS
BINT00: DEC.W TEMP
;16 BIT.W REGISTER..DECREMENT TILL 0000H
JNZ BINT00
MOV.B &P1IN,BTNSAV
;CHECK FOR SWITCH INTERRUPT (XITION TO LO)
INV.B BTNSAV
;CHANGE TO POSITIVE LOGIC
AND.B #01H,BTNSAV
;MASK FOR BIT 0
JZ BINT01
;FALSE INTERRUPT
TST.B OPMODE
;IF OPMODE = SLEEPMODE=0 THEN SET SR ON
; THE STACK TO POWERUP ON RTI
JNZ BINT02
; NOT SLEEP
;ASLEEP
BIC #TBIE,&TB0CTL
;DISABLE TIMER_B OVERFLOW INTERRUPTS
CLR 0(SP)
;SET CPU ACTIVE ON RTI
BINT01: RETI
BINT02: MOV.B BTNSAV,BTNMEM
;SAVE FOR BUTTON CHECK ROUTINE
RETI ; ..
;--------------- END OF BUTTON INTERRUPT
---------------------------------
As you can see the code to detect the bouncing button for 5 ms. if the
button is pressed < 5 ms then it will be ignored. An valid button pressed
will return and wake the CPU up and start the NEWDAY routine (in DOZE). It
will start your program (turn on your device). If it is not from the sleep
mode (OPMODE = 0 operation mode) then it will be OPMODE 1, 2,3, 4 whatever
you named it then you know what to do with the button pressed. Example,
OPMODE 1 is in SET HOUR, the button will increase the HOURS, if the OPMODE 2
is in SET MINUTE, the button pressed will increase MINUTES. And as you know
with port 1 we can have total 8 buttons to do so many thing.
Now for the DOZE, this is the place for the CPU to rest (LPM3) to save
power:
;----------- code for the DOZE
--------------
DOZE: MOV #SFE(CSTACK),SP
;START OF STACK (CLR POSSIBLE PENDING RTI)
BIC.B #01H,&P1DIR
; MAKE P1.0 INPUTS
MOV.B #01H,&P1IES
;INTERUPT EDGE...HI TO LO ON P1.0
MOV.B #01H,&P1IE
;ENABLE P1.0 INTERRUPTS
MOV #0120H,&TBCTL
;RECONDITION TIMERB 32KHZ, CONT UP..CAUTIONARY
ADD #1000H,&TBCCR0
;ADD 125MS TO COMPARE B0 REG (4096/32768)
MOV #0010H,&TBCCTL0
;ENABLE TIMERB COMPARE0 INTERRUPT
;-----------------------------------
DOZ00: MOV #00D8H,SR
;LPMODE3..ENABLE GENERAL INTERRUPT
NOP
;BTTN PRESSES WHILE IN DOZE WILL VECTOR TO
; BINTR AND ReTI BACK TO HERE TO THE LO
PWR mode
;125MS COMPARE WILL VECTOR TO MAIN.
;MAIN WILL TERMINATE WITH A BRANCH BACK
TO DOZE.
; IN ORDER TO SET UP THE SWITCH
INTERRUPTS
; AND ADD 125MS TO THE NEXT COMPARE
INTERRUPT.
JMP DOZ00
;PRECAUTION
;-------------- end code for doze
-----
-
As you see up to now, the program (the CPU) resets at PWRON, loop until the
CPU is stable then go to ENDAY to sleep to save power. If a button is
pressed during sleep mode, the RETI will trigger the SR to turn the CPU ON,
the program will go to NEWDAY:
;----------- code for the NEWDAY ----------------------------
NEWDAY:
.......... DO whatever you have to do to display the device or do something
then branch to DOZE to let the CPU sleep. During the CPU sleep in DOZE, the
timer B compare 0 with 125 ms (1000H will be 125 ms, 2000H will be 250 ms,
and so on ... depends on how many ms seconds you want the button to react.)
BR #DOZE
;--------- end code for NEWDAY ----------------------------
Now the code for the MAIN: the MAIN will be running every 125 ms during
awake mode and you can do different task in the MAIN depends on what you
want to do:
;---------------- Code for MAIN running every 125 ms during awake
-------------
MAIN: MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE WATCHDOG
TIMER,
INC.B EIGHTHS
;INCREMENT 1/8 SEC CTR
AND.B #07H,EIGHTHS
;MASK OFF UNUSED BITS
BIS.W #GIE,SR
;RE-ENABLE GEN INTERRUPTS FOR BTTN PRESSES
MOV.B EIGHTHS,R5
RLA R5
BR MAIN00(R5)
MAIN00: DW JOB0
DW JOB1
DW JOB2
DW JOB3
DW JOB4
DW JOB5
DW JOB6
DW JOB7
JOB0: Do something then ..
BR #DOZE
JOB1: Do something then ..
BR #DOZE
JOB2: Do something then ..
BR #DOZE
JOB3: Do something then ..
BR #DOZE
JOB4: Do something then ..
BR #DOZE
JOB5: Do something then ..
BR #DOZE
JOB6: Do something then ..
BR #DOZE
JOB7: Do something then ..
BR #DOZE
;-------------- end code for MAIN -------------------
This is a complete frame programming for a MSP430F449 chip from start power
up, detect LF and DCO fault to make sure 100% the CPU is stable and back to
sleep, wait for a button pressed to wake up and start a NEWDAY then go back
to sleep. During AWAKE mode, every 125 ms, the CPU will wake up to check
for any task that it has to do, then back to sleep until the program go back
to ENDAY (like 2 hours without a button pressed, the program will go back to
sleep mode.
Finally about TRAPE0, TRAPE2, ... I name it and put a code in it routine to
see if any interrupt occur during my program running so I can trap that
interrupt back to DOZE so I don't have any unwanted interrupt that will make
my program go haywired.
TRAPE0: MOV.B #0E0H,ERROR
... display the ERROR so I know what going all
.. delay the dislpay for 10 seconds ....
BR #DOZE
it is also a good programming when we put all the initialization in one
routine that I called PREP (prepare):
;------------ code to put all initialization in one routine ----------------
PREP: MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE
WATCHDOG TIMER,
MOV.B #032H,&SCFQCTL
;DCOCLK = 50*30.518 = 1.52mhz, MODULATION ON
CLR.B &SCFI0
;DCO RANGE = .65/6mhz
CLR.B &SCFI1
; ..
MOV.B #0B0H,FLL_CTL0
;SELECT.. DCO, LO FREQ, 10pf LOAD
MOV.B #020H,FLL_CTL1
;XT2OFF, ACLK/1
CLR.B &IE1
;CAUTIONARY DISABLE MODULE INTERRUPT
REGISTERS
CLR.B &IE2
CLR.B &IFG1
;CAUTIONARY CLEAR MODULE INTERRUPT FLAGS
CLR.B &IFG2
; ..
CLR.B &ME1
;CAUTIONARY MODULE DISABLES
CLR.B &ME2
; ..
;-------------- TIMER A SETUP
-----
----------
; SET UP TIMER A FOR SOME USE, LIKE A PIEZO TO MAKE A SOUND OR SOMETHING
;----
--------------
MOV #0104H,&TACTL
;TIMERA ACLK, STOPPED, CLEARED
MOV #0008H,&CCR0
;COMPARE REG0 TO 7(DELAYED), TACL0 4096hz
MOV #0004H,&CCR2
;COMPARE REG1 TO 4, TACL1 (50%DC)
MOV #00E0H,&CCTL2
;PREPARE OUTP UNIT1 FOR RESET/SET
CLR &CCTL0
;CLR CAP/COMP CONTROL REG0
BIC #0010H,&TACTL
;STOP 4KHZ PIEZO DRIVE
;------------ PORT1 ----------------
;P1.0 button
;P1.1 to P1.7 N/U
CLR.B &P1IES
;INTERUPT EDGE...LOW TO HI
CLR.B &P1OUT
;SET PORT1 OUTPUT LATCHES LOW
MOV.B #0FEH,&P1DIR
;ALL OUTPUT EXCEPT P1.0 is INPUT
CLR.B &P1IE
;DISABLE P1 INTERRUPTS
CLR.B &P1IFG
;RESET POSSIBLE INTERRUPT FLAG
CLR.B &P1SEL
;Make port 1 to be all IO line
;PORT2
;PORT3
;PORT4
;PORT5
;PORT6
CLR &ADC12CTL0
;CLEAR A/D CONTROL REGISTERS
CLR &ADC12CTL1 ; ..
CLR &ADC12IFG
;CLEAR INTERRUPT ENABLE FLAG REGS
CLR &ADC12IE ; ..
RET
;---------- end code for PREP -------
You can put the PREP right after the CPU is stable then clear RAM, read
EEPROM ... before put the CPU into sleep mode.
I hope to help you guy with some information that I worked in the field of
assembler for the MSP430.
Anthony Ha
Reply by ●October 23, 20132013-10-23
Hi
My technician was the one who reported to me that it had locked up
completely. I conducted some tests and found that it was only one area of
the program that did not work. I now do not believe it is a NMI problem.
However, your program looks interesting and I will study it a while.
Thanks
Peter
My technician was the one who reported to me that it had locked up
completely. I conducted some tests and found that it was only one area of
the program that did not work. I now do not believe it is a NMI problem.
However, your program looks interesting and I will study it a while.
Thanks
Peter
Reply by ●October 24, 20132013-10-24
This is actually typical of a routine that has a subtle bug. Possibly a
corrupted stack. You can test this with a RAM counter (since a corrupted
PC doesn't force a POR), just don't init that word/byte on power up, or
set flags to say it has been a POR. then use a LED to flash if the
counter is non-zero. If it is disappearing up its own bum then you will
need to trap the routine. If you can only clear by a reset then it could
still be an NMI or simple PC corruption.
Watch the sample code, the switch check is polled, and inefficient, and
the clearing of SP prior to entering a sleep mode can be dangerous,
sometimes routines may be left operating, unless you explicitly
structure your code to clear all pending tasks before sleeping.
Al
corrupted stack. You can test this with a RAM counter (since a corrupted
PC doesn't force a POR), just don't init that word/byte on power up, or
set flags to say it has been a POR. then use a LED to flash if the
counter is non-zero. If it is disappearing up its own bum then you will
need to trap the routine. If you can only clear by a reset then it could
still be an NMI or simple PC corruption.
Watch the sample code, the switch check is polled, and inefficient, and
the clearing of SP prior to entering a sleep mode can be dangerous,
sometimes routines may be left operating, unless you explicitly
structure your code to clear all pending tasks before sleeping.
Al
Reply by ●October 24, 20132013-10-24
I was writing assembler for the SANYO chip before I change to TI MSP430. I wrote
programs for Scuba Dive Computers and Dive Watches using MSP430F44X,
MSP430F5437A, MSP430F5635, .... and you can find the name of the Dive Computers
like: Data PRO, Data MASK, HUD (Head Up Mask for the US NAVY) Aeris MASK, AERIS
AI, AERIS A100, AERIS A300, BISM GRANDE, BEAUCHAT Manta .= . .. Dive Watches
like ATOM, OC1, OCS, GEO, Aeris F10, Aeris F11, ..... or th= e company name like
Oceanic, Aeris, Hollis, Bism, Beauchat ......
Anthony Ha
Anthony Ha
Reply by ●October 24, 20132013-10-24
??
On 24/10/2013 3:21 PM, a...@gmail.com wrote:
> I was writing assembler for the SANYO chip before I change to TI
> MSP430. I wrote programs for Scuba Dive Computers and Dive Watches
> using MSP430F44X, MSP430F5437A, MSP430F5635, .... and you can find the
> name of the Dive Computers like: Data PRO, Data MASK, HUD (Head Up
> Mask for the US NAVY) Aeris MASK, AERIS AI, AERIS A100, AERIS A300,
> BISM GRANDE, BEAUCHAT Manta ..... Dive Watches like ATOM, OC1, OCS,
> GEO, Aeris F10, Aeris F11, ..... or the company name like Oceanic,
> Aeris, Hollis, Bism, Beauchat ......
> Anthony Ha
On 24/10/2013 3:21 PM, a...@gmail.com wrote:
> I was writing assembler for the SANYO chip before I change to TI
> MSP430. I wrote programs for Scuba Dive Computers and Dive Watches
> using MSP430F44X, MSP430F5437A, MSP430F5635, .... and you can find the
> name of the Dive Computers like: Data PRO, Data MASK, HUD (Head Up
> Mask for the US NAVY) Aeris MASK, AERIS AI, AERIS A100, AERIS A300,
> BISM GRANDE, BEAUCHAT Manta ..... Dive Watches like ATOM, OC1, OCS,
> GEO, Aeris F10, Aeris F11, ..... or the company name like Oceanic,
> Aeris, Hollis, Bism, Beauchat ......
> Anthony Ha
Reply by ●October 24, 20132013-10-24
This is not a complete program, just some parts of a layout. I wrote assembler
over 20 years for Scuba Diving Industry and never had a recall. Ofcourse, some
units might be defected like leaking but the firmware to control the CPU is very
low power. It lasts for years because when it goes to sleep mode, it is only a
few micro amp. Ofcourse as you said, all ports have to be under control, as a
port is left high of floating, it might draw current.
It is not only a sample program, but it is a part of my life also. The main code for the Scuba Dive Computer is about over 30 thousand line of code The algorithm for the diving computer). Other part like read write EEPROM, Communicating to the PC thru USB (or Bluetooth), BSL code (that I gave you guy in another email), .....
I have two kinds of programs: One for the dive watches, and one for the Scuba dive Computers. Both of them have the same structure, that is when it is awake, it is a 125 ms interrupt (in DOZE) to check for any task (in MAIN= ) that the CPU has to do then back to sleep. The different between the two is when power up, the watches will stay awake until is is put in to deep sleep for storage. The dive computer after power up, it is put into sleep as you can see in the sample program. Ofcourse, I removed all the others code that I thought it would make you confuse or I had to explain if I included the code ịn.
Anthony Ha
It is not only a sample program, but it is a part of my life also. The main code for the Scuba Dive Computer is about over 30 thousand line of code The algorithm for the diving computer). Other part like read write EEPROM, Communicating to the PC thru USB (or Bluetooth), BSL code (that I gave you guy in another email), .....
I have two kinds of programs: One for the dive watches, and one for the Scuba dive Computers. Both of them have the same structure, that is when it is awake, it is a 125 ms interrupt (in DOZE) to check for any task (in MAIN= ) that the CPU has to do then back to sleep. The different between the two is when power up, the watches will stay awake until is is put in to deep sleep for storage. The dive computer after power up, it is put into sleep as you can see in the sample program. Ofcourse, I removed all the others code that I thought it would make you confuse or I had to explain if I included the code ịn.
Anthony Ha
Reply by ●October 24, 20132013-10-24
My point was that your program structure and implementation has some
potential issues, and could be improved. I've been programming for over
40 years and it makes no difference. Other than lots of experience,
which I believe gives me the right to comment too, it doesn't make me
perfect or immune to doing dumb shit. Nor does a program which is
reliable mean that it is necessarily perfect for other tasks, or even
well written. It is great that you spend the time to try and help
people, that is the whole purpose of the group, and my intention wasn't
to knock you down, but to try and highlight what could cause some issues
for Peter (the OP), and by doing so also help him out and give him options.
I'm especially very happy to see another assembly programmer here, we
are a dying breed, so huge kudos for that.
Sorry i offended, it wasn't meant to offend, but to clarify.
Al
potential issues, and could be improved. I've been programming for over
40 years and it makes no difference. Other than lots of experience,
which I believe gives me the right to comment too, it doesn't make me
perfect or immune to doing dumb shit. Nor does a program which is
reliable mean that it is necessarily perfect for other tasks, or even
well written. It is great that you spend the time to try and help
people, that is the whole purpose of the group, and my intention wasn't
to knock you down, but to try and highlight what could cause some issues
for Peter (the OP), and by doing so also help him out and give him options.
I'm especially very happy to see another assembly programmer here, we
are a dying breed, so huge kudos for that.
Sorry i offended, it wasn't meant to offend, but to clarify.
Al