Problems with MSP430F2132
I put my program back to changing just the setting of TOS (0x400) and the
fault returned. This is either not the fault or I have more than 1 fault.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 29 October 2013 12:45 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
You're setting TOS (SP) to an odd number TOS should be end of RAM + 1, that
is your bug here. so set it to 0X0400
Al
On 29/10/2013 1:46 PM, Peter Grey wrote:
Hi Anthony
I have solved my problem. In my program I setup the stack at RESET and then
call a subroutine to set up the ports and the clock.
Reset
mov.w #3FFh,SP ; Initialize
stackpointer
call #Setup
In Setup I then setup the clock
clr.b &DCOCTL
mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
mov.b &CALDCO_16MHZ,&DCOCTL
I then set up the port direction and initial states
SetupP1 mov.b #0f3h,&P1DIR ;
11110011
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
SetupP2 mov.b #0E8h,&P2DIR ;11101000,
mov.b #07h,&P2SEL2 ;A0-A2
clr.b &P2OUT
bis.b #LIS_CS,&P2OUT
clr.b MDA_COUNTER
clr.b DURESS_COUNTER
SetupP3 mov.b #0B0h,&P3DIR ;10110000
clr.b &P3OUT
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
Finally I do a ret
My fix was to run this subroutine a second time and all my problems
disappeared??
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Saturday, 26 October 2013 12:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
I have just sent you an email that I explained something, but I don't know
that is what you want. If you think part of your code has problem, you can
zip that part and send it to me as an attachment file (txt file). I can read
and have my opinion for you.
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/25/2013 7:48:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Anthony
I can see what you are doing at RESET. It is similar to mine but I have a
MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
see how you ever exit this. There is no RETI? What is the routine supposed
to do apart from re-initialising the stack and setting up the registers
again? I turn on a LED in the NMI interrupt routine but I never see this
happen. I am beginning to think that this may not be a NMI problem, but
something silly I am doing.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Wednesday, 23 October 2013 11:40 AM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
-------Original Message-------
From: Peter Grey
Date: 10/22/2013 6:32:41 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
Content-Type: Text/Plain;
charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable
Peter,
It is the best to use this code:
MOV.W #SFE(CSTACK),SP ;START OF STACK
It doesn't matter what is the MSP430 that you are using.
Al is correct in this case you have to use
mov.w #0400h,SP ; Initialize stackpointer
But like I said, the best code is:
MOV.W #SFE(CSTACK),SP ;START OF STACK
Also Al points out you don't have to clear DCOCTL
clr.b &DCOCTL
;----
PORT 1 setup:
The first line of code is enough, you don't have to have the next two lines
of code.
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
If you don't have the first line CLR.B &P1OUT, then you can combine both
lines to become:
BIC.B #EN_BUZZER+EN_30V,&P1OUT
As I said, the first line is enough, you don't have to have the next two
lines.
;--------
PORT 3 setup:
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
You can combine both lines of code to become:
BIS.B #TR_SDI+nSS_CONF+nSS_DATA,&P3OUT
;---------
I don't see anywhere you disable the watchdog timer. Always disable the
watch dog timer if you don't use it for any purposes:
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE WATCHDOG TIMER,
So , I suggest you rewrite your RESET as follow:
RESET: DINT
; disable all interrupt before entering your program.
Wait until you setup every thing first
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; DISABLE
WATCHDOG TIMER,
CLR.B &P1IE
; CLEAR PORT 1 INTERRUPT
CLR.B &P2IE
; CLEAR PORT 2 INTERRUPT
MOV.W #SFE(CSTACK),SP
;START OF STACK
CALL #SETUP
MOV.W #SFB(DATA16_I),R15
;RAM START LOCATION
PWR00: CLR.W 0(R15)
;CLR ALL RAM MEMORY LOCATIONS
INCD.W R15 ;
CMP.W #LAST_VARIABLE,R15
;TEST R15 FOR LAST LOCATION
JLO PWR00
; NOT YET
; RAM CLEARED
;------------------------
I see you clear some variables in the SETUP, so I suggest you don't have to
clear individual variable, but use a loop as my suggestion above after setup
You declare variables in DATA16_I
RSEG DATA16_I
MDA_COUNTER DS 1
DURESS_COUNTER DS 1
....................................................
LAST_VARIABLE DS 1
If you post your code, Al and I can help you to find something if somethig
wrong.
Anthony Ha
-------Original Message-------
From: Onestone
Date: 10/28/2013 9:49:21 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
It is also unnecessary to first clear DCOCTL before setting it to the stored
calibratiob value, however that is trivia.
Al
On 29/10/2013 1:46 PM, Peter Grey wrote:
Hi Anthony
I have solved my problem. In my program I setup the stack at RESET and then
call a subroutine to set up the ports and the clock.
Reset
mov.w #3FFh,SP ; Initialize
stackpointer
call #Setup
In Setup I then setup the clock
clr.b &DCOCTL
mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
mov.b &CALDCO_16MHZ,&DCOCTL
I then set up the port direction and initial states
SetupP1 mov.b #0f3h,&P1DIR ;
11110011
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
SetupP2 mov.b #0E8h,&P2DIR ;11101000,
mov.b #07h,&P2SEL2 ;A0-A2
clr.b &P2OUT
bis.b #LIS_CS,&P2OUT
clr.b MDA_COUNTER
clr.b DURESS_COUNTER
SetupP3 mov.b #0B0h,&P3DIR ;10110000
clr.b &P3OUT
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
Finally I do a ret
My fix was to run this subroutine a second time and all my problems
disappeared??
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Saturday, 26 October 2013 12:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
I have just sent you an email that I explained something, but I don't know
that is what you want. If you think part of your code has problem, you can
zip that part and send it to me as an attachment file (txt file). I can read
and have my opinion for you.
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/25/2013 7:48:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Anthony
I can see what you are doing at RESET. It is similar to mine but I have a
MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
see how you ever exit this. There is no RETI? What is the routine supposed
to do apart from re-initialising the stack and setting up the registers
again? I turn on a LED in the NMI interrupt routine but I never see this
happen. I am beginning to think that this may not be a NMI problem, but
something silly I am doing.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Wednesday, 23 October 2013 11:40 AM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
-------Original Message-------
From: Peter Grey
Date: 10/22/2013 6:32:41 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al,
Thanks for the detailed reply. I must admit I have not used NMI since I was
using the PDP minis, 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
--------------Boundary-00=_TT1FQL80000000000000
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Peter, Â It is the best to use this
code: Â MOV.WÂ Â Â Â Â
#SFE(CSTACK),SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
           Â
;START OF STACK It doesn't matter what is the
MSP430 that you are using. Â Â Al is correct in this case you have to
use  mov.w Â
#0400h,SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â
; Initialize stackpointer<?XML:NAMESPACE PREFIX = "O"
/> Â But like I said, the best code
is: Â MOV.WÂ Â Â Â Â
#SFE(CSTACK),SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
           Â
;START OF STACK Â Â Also Al points out you don't have
to clear DCOCTL   clr.b     Â
&DCOCTL Â ;---- PORT 1 setup: The first line of code is enough, you
don't have to have the next two lines of code.  clr.b Â
&P1OUTÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
; SET LOW            bic.b  #EN_BUZZER,&P1OUT                      ;turn off beeper            bic.b  #EN_30V,&P1OUT If you don't have the first line
CLR.BÂ Â &P1OUT, then you can combine both lines to become:
 BIC.B     Â
#EN_BUZZER+EN_30V,&P1OUT Â As I said, the first line is enough,
you don't have to have the next two lines.  ;-------- PORT 3 setup:  bis.b Â
#TR_SDI,&P3OUT           bis.b       #nSS_CONF+nSS_DATA,&P3OUT            ;set both high  You can combine both lines of code to
become: BIS.BÂ Â Â Â Â Â Â
#TR_SDI+nSS_CONF+nSS_DATA,&P3OUT Â Â Â ;--------- I don't see anywhere you disable
the watchdog timer. Always disable the watch dog timer if you don't use it
for any purposes: Â MOV.WÂ Â Â Â Â Â Â Â
#WDTPW+WDTHOLD,&WDTCTLÂ Â Â Â Â Â Â Â Â
; DISABLE WATCHDOG TIMER, Â So , I suggest you rewrite your RESET
as follow: Â RESET:Â
DINTÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ;
disable all interrupt before entering your program. Wait until you setup every
thing first               Â
MOV.WÂ Â Â Â Â Â Â Â
#WDTPW+WDTHOLD,&WDTCTLÂ Â Â Â Â Â Â Â Â Â
; DISABLE WATCHDOG
TIMER, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
CLR.BÂ Â Â Â Â Â Â Â Â Â Â
&P1IEÂ Â Â Â Â Â Â Â Â
           Â
           Â
        Â
    ; CLEAR PORT 1 INTERRUPT            Â
CLR.BÂ Â Â Â Â Â Â Â Â Â Â Â &P2IEÂ Â Â
           Â
           Â
           Â
       ; CLEAR PORT 2 INTERRUPT            Â
           Â
MOV.WÂ Â Â Â Â Â Â Â
#SFE(CSTACK),SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
           Â
   ;START OF
STACK Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
CALLÂ Â Â Â Â Â Â Â Â
   #SETUP            Â
           Â
MOV.W Â Â Â Â Â Â Â
#SFB(DATA16_I),R15Â Â Â Â Â Â Â Â Â
           Â
   ;RAM START LOCATION PWR00: CLR.W        0(R15)                                               ;CLR ALL RAM MEMORY LOCATIONS              INCD.W       R15                  ;              CMP.W       #LAST_VARIABLE,R15                        ;TEST R15 FOR LAST LOCATION              JLO             PWR00                                            ; NOT YET                                                                                                                 ; RAM CLEARED ;------------------------  I see you clear some variables in the
SETUP, so I suggest you don't have to clear individual variable, but use a
loop as my suggestion above after setup. You declare variables in DATA16_I
            Â
RSEGÂ Â Â Â Â Â Â Â Â Â Â Â
DATA16_I Â MDA_COUNTER Â Â Â Â Â Â Â Â Â
DSÂ Â Â 1 DURESS_COUNTERÂ Â Â Â Â DSÂ Â Â
1 .................................................... LAST_VARIABLEÂ Â Â Â Â Â Â Â Â
DSÂ Â Â 1 Â Â If you post your code, Al and I can
help you to find something if somethig wrong.   Anthony Ha       -------Original Message-------   It is also unnecessary to first clear DCOCTL before setting it
to the stored calibratiob value, however that is trivia.Al On 29/10/2013 1:46 PM, Peter Grey wrote: Hi Anthony  I have solved my problem. In my program I setup the stack at RESET and then call a subroutine to set up the ports and the clock. Reset                                    mov.w  #3FFh,SP               ; Initialize stackpointer                             call         #Setup In Setup I then setup the clock                         clr.b      &DCOCTL mov.b  &CALBC1_16MHZ,&BCSCTL1  ; Set DCO to 8MHz                           mov.b  &CALDCO_16MHZ,&DCOCTL  I then set up the port direction and initial states                         SetupP1    mov.b  #0f3h,&P1DIR           ; 11110011            clr.b  &P1OUT                 ; SET LOW            bic.b  #EN_BUZZER,&P1OUT                      ;turn off beeper            bic.b  #EN_30V,&P1OUT            SetupP2    mov.b  #0E8h,&P2DIR           ;11101000,            mov.b   #07h,&P2SEL2                  ;A0-A2              clr.b  &P2OUT              bis.b  #LIS_CS,&P2OUT                clr.b  MDA_COUNTER                clr.b  DURESS_COUNTER        SetupP3    mov.b  #0B0h,&P3DIR           ;10110000            clr.b  &P3OUT            bis.b  #TR_SDI,&P3OUT           bis.b       #nSS_CONF+nSS_DATA,&P3OUT            ;set both high Finally I do a ret My fix was to run this subroutine a second time and all my problems disappeared??  Thanks  Peter From:
m... [mailto:m...] On Behalf Of
a...@gmail.com Â
|
Content-Type: Text/Plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Peter,
Try
MOV.W #SFE(CSTACK),SP ;START OF STACK
or
MOV.W #0300h,SP
START OF STACK
I don't remember exactly but 0400h doesn't work then it has to be #0300h,SP
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/28/2013 10:51:12 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al
I put my program back to changing just the setting of TOS (0x400) and the
fault returned. This is either not the fault or I have more than 1 fault.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 29 October 2013 12:45 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
You're setting TOS (SP) to an odd number TOS should be end of RAM + 1, that
is your bug here. so set it to 0X0400
Al
On 29/10/2013 1:46 PM, Peter Grey wrote:
Hi Anthony
I have solved my problem. In my program I setup the stack at RESET and then
call a subroutine to set up the ports and the clock.
Reset
mov.w #3FFh,SP ; Initialize
stackpointer
call #Setup
In Setup I then setup the clock
clr.b &DCOCTL
mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
mov.b &CALDCO_16MHZ,&DCOCTL
I then set up the port direction and initial states
SetupP1 mov.b #0f3h,&P1DIR ;
11110011
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
SetupP2 mov.b #0E8h,&P2DIR ;11101000,
mov.b #07h,&P2SEL2 ;A0-A2
clr.b &P2OUT
bis.b #LIS_CS,&P2OUT
clr.b MDA_COUNTER
clr.b DURESS_COUNTER
SetupP3 mov.b #0B0h,&P3DIR ;10110000
clr.b &P3OUT
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
Finally I do a ret
My fix was to run this subroutine a second time and all my problems
disappeared??
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Saturday, 26 October 2013 12:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
I have just sent you an email that I explained something, but I don't know
that is what you want. If you think part of your code has problem, you can
zip that part and send it to me as an attachment file (txt file). I can read
and have my opinion for you.
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/25/2013 7:48:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Anthony
I can see what you are doing at RESET. It is similar to mine but I have a
MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
see how you ever exit this. There is no RETI? What is the routine supposed
to do apart from re-initialising the stack and setting up the registers
again? I turn on a LED in the NMI interrupt routine but I never see this
happen. I am beginning to think that this may not be a NMI problem, but
something silly I am doing.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Wednesday, 23 October 2013 11:40 AM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
-------Original Message-------
From: Peter Grey
Date: 10/22/2013 6:32:41 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al,
Thanks for the detailed reply. I must admit I have not used NMI since I was
using the PDP minis, 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
--------------Boundary-00=_ET2FG6G0000000000000
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Peter,  Try   MOV.W    Â
#SFE(CSTACK),SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
           Â
;START OF STACK or   MOV.W    Â
#0300h,SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
           Â
           Â
;START OF STACK I don't remember exactly but
0400h doesn't work then it has to be #0300h,SP  Anthony Ha     -------Original Message-------  From: Peter Grey Date: 10/28/2013 10:51:12
PM To: m... Subject: RE: [msp430]
Problems with MSP430F2132  Hi Al  I put my program back to changing just the setting of TOS (0x400) and the fault returned. This is either not the fault or I have more than 1 fault.  Thanks  Peter   From: m...
[mailto:m...] On Behalf Of Onestone Â
On 29/10/2013 1:46 PM, Peter Grey wrote: Hi Anthony  I have solved my problem. In my program I setup the stack at RESET and then call a subroutine to set up the ports and the clock. Reset                                    mov.w  #3FFh,SP               ; Initialize stackpointer                             call         #Setup In Setup I then setup the clock                         clr.b      &DCOCTL mov.b  &CALBC1_16MHZ,&BCSCTL1  ; Set DCO to 8MHz                           mov.b  &CALDCO_16MHZ,&DCOCTL  I then set up the port direction and initial states                         SetupP1    mov.b  #0f3h,&P1DIR           ; 11110011            clr.b  &P1OUT                 ; SET LOW            bic.b  #EN_BUZZER,&P1OUT                      ;turn off beeper            bic.b  #EN_30V,&P1OUT            SetupP2    mov.b  #0E8h,&P2DIR           ;11101000,            mov.b   #07h,&P2SEL2                  ;A0-A2              clr.b  &P2OUT              bis.b  #LIS_CS,&P2OUT                clr.b  MDA_COUNTER                clr.b  DURESS_COUNTER        SetupP3    mov.b  #0B0h,&P3DIR           ;10110000            clr.b  &P3OUT            bis.b  #TR_SDI,&P3OUT           bis.b       #nSS_CONF+nSS_DATA,&P3OUT            ;set both high Finally I do a ret My fix was to run this subroutine a second time and all my problems disappeared??  Thanks  Peter From:
m... [mailto:m...] On
Behalf Of anthonyh...@gmail.com Â
|
The RAM for the F2132 is at 0x200 to 0x3FF.
Thanks for your help. I would like to spend a bit more time on this but I
have a few orders to get out and it is near the end of the month so
financial pressure is on. Please pardon the delays in getting back to you.
The other major difference between our code is that I use mov #0400h,SP
rather than mov.w #0400h,SP. As far as I can see this is exactly equivalent.
I have also tried other numbers such as 0x3fe but the error is the same.
I will clear up these orders first and then focus properly on this problem.
Cheers
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Tuesday, 29 October 2013 2:18 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
Try
MOV.W #SFE(CSTACK),SP ;START OF STACK
or
MOV.W #0300h,SP
;START OF STACK
I don't remember exactly but 0400h doesn't work then it has to be #0300h,SP
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/28/2013 10:51:12 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al
I put my program back to changing just the setting of TOS (0x400) and the
fault returned. This is either not the fault or I have more than 1 fault.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 29 October 2013 12:45 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
You're setting TOS (SP) to an odd number TOS should be end of RAM + 1, that
is your bug here. so set it to 0X0400
Al
On 29/10/2013 1:46 PM, Peter Grey wrote:
Hi Anthony
I have solved my problem. In my program I setup the stack at RESET and then
call a subroutine to set up the ports and the clock.
Reset
mov.w #3FFh,SP ; Initialize
stackpointer
call #Setup
In Setup I then setup the clock
clr.b &DCOCTL
mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
mov.b &CALDCO_16MHZ,&DCOCTL
I then set up the port direction and initial states
SetupP1 mov.b #0f3h,&P1DIR ;
11110011
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
SetupP2 mov.b #0E8h,&P2DIR ;11101000,
mov.b #07h,&P2SEL2 ;A0-A2
clr.b &P2OUT
bis.b #LIS_CS,&P2OUT
clr.b MDA_COUNTER
clr.b DURESS_COUNTER
SetupP3 mov.b #0B0h,&P3DIR ;10110000
clr.b &P3OUT
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
Finally I do a ret
My fix was to run this subroutine a second time and all my problems
disappeared??
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Saturday, 26 October 2013 12:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
I have just sent you an email that I explained something, but I don't know
that is what you want. If you think part of your code has problem, you can
zip that part and send it to me as an attachment file (txt file). I can read
and have my opinion for you.
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/25/2013 7:48:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Anthony
I can see what you are doing at RESET. It is similar to mine but I have a
MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
see how you ever exit this. There is no RETI? What is the routine supposed
to do apart from re-initialising the stack and setting up the registers
again? I turn on a LED in the NMI interrupt routine but I never see this
happen. I am beginning to think that this may not be a NMI problem, but
something silly I am doing.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Wednesday, 23 October 2013 11:40 AM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
-------Original Message-------
From: Peter Grey
Date: 10/22/2013 6:32:41 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
Content-Type: Text/Plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Peter,
As I said, use this code and you don't have to worry about what chip you are
using:
MOV.W #SFE(CSTACK),SP ;START OF STACK
Anthony
-------Original Message-------
From: Peter Grey
Date: 10/28/2013 11:44:07 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Anthony
The RAM for the F2132 is at 0x200 to 0x3FF.
Thanks for your help. I would like to spend a bit more time on this but I
have a few orders to get out and it is near the end of the month so
financial pressure is on. Please pardon the delays in getting back to you.
The other major difference between our code is that I use mov #0400h,SP
rather than mov.w #0400h,SP. As far as I can see this is exactly equivalent.
I have also tried other numbers such as 0x3fe but the error is the same.
I will clear up these orders first and then focus properly on this problem.
Cheers
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Tuesday, 29 October 2013 2:18 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
Try
MOV.W #SFE(CSTACK),SP ;START OF STACK
or
MOV.W #0300h,SP
START OF STACK
I don't remember exactly but 0400h doesn't work then it has to be #0300h,SP
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/28/2013 10:51:12 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al
I put my program back to changing just the setting of TOS (0x400) and the
fault returned. This is either not the fault or I have more than 1 fault.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 29 October 2013 12:45 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
You're setting TOS (SP) to an odd number TOS should be end of RAM + 1, that
is your bug here. so set it to 0X0400
Al
On 29/10/2013 1:46 PM, Peter Grey wrote:
Hi Anthony
I have solved my problem. In my program I setup the stack at RESET and then
call a subroutine to set up the ports and the clock.
Reset
mov.w #3FFh,SP ; Initialize
stackpointer
call #Setup
In Setup I then setup the clock
clr.b &DCOCTL
mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
mov.b &CALDCO_16MHZ,&DCOCTL
I then set up the port direction and initial states
SetupP1 mov.b #0f3h,&P1DIR ;
11110011
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
SetupP2 mov.b #0E8h,&P2DIR ;11101000,
mov.b #07h,&P2SEL2 ;A0-A2
clr.b &P2OUT
bis.b #LIS_CS,&P2OUT
clr.b MDA_COUNTER
clr.b DURESS_COUNTER
SetupP3 mov.b #0B0h,&P3DIR ;10110000
clr.b &P3OUT
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
Finally I do a ret
My fix was to run this subroutine a second time and all my problems
disappeared??
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Saturday, 26 October 2013 12:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
I have just sent you an email that I explained something, but I don't know
that is what you want. If you think part of your code has problem, you can
zip that part and send it to me as an attachment file (txt file). I can read
and have my opinion for you.
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/25/2013 7:48:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Anthony
I can see what you are doing at RESET. It is similar to mine but I have a
MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
see how you ever exit this. There is no RETI? What is the routine supposed
to do apart from re-initialising the stack and setting up the registers
again? I turn on a LED in the NMI interrupt routine but I never see this
happen. I am beginning to think that this may not be a NMI problem, but
something silly I am doing.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Wednesday, 23 October 2013 11:40 AM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
-------Original Message-------
From: Peter Grey
Date: 10/22/2013 6:32:41 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al,
Thanks for the detailed reply. I must admit I have not used NMI since I was
using the PDP minis, 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
--------------Boundary-00=_KL4F6RO0000000000000
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Peter, Â As I said, use this code and you
don't have to worry about what chip you are using: Â MOV.WÂ Â Â Â Â
#SFE(CSTACK),SPÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
           Â
;START OF STACK   Anthony    -------Original Message-------  From: Peter Grey Date: 10/28/2013 11:44:07
PM To: m... Subject: RE: [msp430]
Problems with MSP430F2132  Anthony The RAM for the F2132 is at 0x200 to 0x3FF.  Thanks for your help. I would like to spend a bit more time on this but I have a few orders to get out and it is near the end of the month so financial pressure is on. Please pardon the delays in getting back to you. The other major difference between our code is that I use mov #0400h,SP rather than mov.w #0400h,SP. As far as I can see this is exactly equivalent. I have also tried other numbers such as 0x3fe but the error is the same. I will clear up these orders first and then focus properly on this problem.  Cheers  Peter  From:
m... [mailto:m...] On Behalf Of a...@gmail.com Â
|
worked it out! I get around this by adding the following at the end of
my *.h files:-
************************************************************/
RAMSTART EQU 0x0200
RAMEND EQU 0x03FF
BOOTSTART EQU 0x0C00
BOOTEND EQU 0x0FFF
FLASHSTART EQU 0xC000
INFOD EQU 0x1000
INFOC EQU 0x1040
INFOB EQU 0x1080
INFOA EQU 0x10C0
INT_TABLE EQU 0xFFE0
TOS EQU RAMEND+1
Then I just have to refer to the same named label each time. I try to
absolutely avoid any absolute values in functional code.
Al
On 29/10/2013 3:59 PM, Peter Grey wrote:
> Hi Al
>
> Thank you for that. You would be surprised at how many times I have
> done this!! Can you explain why I get over the problem by calling this
> subroutine twice?
>
> Cheers
>
> Peter
>
> *From:*m... [mailto:m...] *On
> Behalf Of *Onestone
> *Sent:* Tuesday, 29 October 2013 12:45 PM
> *To:* m...
> *Subject:* Re: [msp430] Problems with MSP430F2132
>
> You're setting TOS (SP) to an odd number TOS should be end of RAM + 1,
> that is your bug here. so set it to 0X0400
>
> Al
>
> On 29/10/2013 1:46 PM, Peter Grey wrote:
>
> Hi Anthony
>
> I have solved my problem. In my program I setup the stack at RESET
> and then call a subroutine to set up the ports and the clock.
>
> Reset
>
> mov.w #3FFh,SP ; Initialize stackpointer
>
> call #Setup
>
> In Setup I then setup the clock
>
> clr.b &DCOCTL
>
> mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
>
> mov.b &CALDCO_16MHZ,&DCOCTL
>
> I then set up the port direction and initial states
>
> SetupP1 mov.b #0f3h,&P1DIR ; 11110011
>
> clr.b &P1OUT ; SET LOW
>
> bic.b #EN_BUZZER,&P1OUT ;turn off beeper
>
> bic.b #EN_30V,&P1OUT
>
> SetupP2 mov.b #0E8h,&P2DIR ;11101000,
>
> mov.b #07h,&P2SEL2 ;A0-A2
>
> clr.b &P2OUT
>
> bis.b #LIS_CS,&P2OUT
>
> clr.b MDA_COUNTER
>
> clr.b DURESS_COUNTER
>
> SetupP3 mov.b #0B0h,&P3DIR ;10110000
>
> clr.b &P3OUT
>
> bis.b #TR_SDI,&P3OUT
>
> bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
>
> Finally I do a ret
>
> My fix was to run this subroutine a second time and all my
> problems disappeared??
>
> Thanks
>
> Peter
>
> *From:*m...
> [mailto:m...] *On Behalf Of
> *a...@gmail.com
> *Sent:* Saturday, 26 October 2013 12:57 PM
> *To:* m...
> *Subject:* RE: [msp430] Problems with MSP430F2132
>
> Peter,
>
> I have just sent you an email that I explained something, but I
> don't know that is what you want. If you think part of your code
> has problem, you can zip that part and send it to me as an
> attachment file (txt file). I can read and have my opinion for you.
>
> Anthony Ha
>
> /-------Original Message-------/
>
> */From:/*Peter Grey */Date:/*10/25/2013 7:48:57 PM
>
> */To:/*m... */Subject:/*RE: [msp430] Problems with MSP430F2132
>
> Hi Anthony
>
> I can see what you are doing at RESET. It is similar to mine but I
> have a MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt
> (DOZE), I cannot see how you ever exit this. There is no RETI?
> What is the routine supposed to do apart from re-initialising the
> stack and setting up the registers again? I turn on a LED in the
> NMI interrupt routine but I never see this happen. I am beginning
> to think that this may not be a NMI problem, but something silly I
> am doing.
>
> Thanks
>
> Peter
>
> *From:*m...
> [mailto:m...] *On Behalf Of
> *a...@gmail.com
> *Sent:* Wednesday, 23 October 2013 11:40 AM
> *To:* m...
> *Subject:* RE: [msp430] Problems with MSP430F2132
> 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
>
> /-------Original Message-------/
>
> */From:/*Peter Grey */Date:/*10/22/2013 6:32:41 PM
>
> */To:/*m... */Subject:/*RE: [msp430] Problems with MSP430F2132
>
> 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
>
>
>
>
exist, or you need to leave in elements of the compiler to leave it there
Al
On 29/10/2013 5:26 PM, a...@gmail.com wrote:
> Peter,
> As I said, use this code and you don't have to worry about what chip
> you are using:
> MOV.W #SFE(CSTACK),SP ;START OF STACK
> Anthony
> /-------Original Message-------/
> /*From:*/ Peter Grey
> /*Date:*/ 10/28/2013 11:44:07 PM
> /*To:*/ m...
> /*Subject:*/ RE: [msp430] Problems with MSP430F2132
>
> Anthony
>
> The RAM for the F2132 is at 0x200 to 0x3FF.
>
> Thanks for your help. I would like to spend a bit more time on this
> but I have a few orders to get out and it is near the end of the month
> so financial pressure is on. Please pardon the delays in getting back
> to you. The other major difference between our code is that I use mov
> #0400h,SP rather than mov.w #0400h,SP. As far as I can see this is
> exactly equivalent. I have also tried other numbers such as 0x3fe but
> the error is the same.
>
> I will clear up these orders first and then focus properly on this
> problem.
>
> Cheers
>
> Peter
>
> *From:*m... [mailto:m...] *On
> Behalf Of *a...@gmail.com
> *Sent:* Tuesday, 29 October 2013 2:18 PM
> *To:* m...
> *Subject:* RE: [msp430] Problems with MSP430F2132
> Peter,
>
> Try
>
> MOV.W #SFE(CSTACK),SP ;START OF STACK
>
> or
>
> MOV.W #0300h,SP ;START OF STACK
>
> I don't remember exactly but 0400h doesn't work then it has to be
> #0300h,SP
>
> Anthony Ha
>
> /-------Original Message-------/
>
> */From:/*Peter Grey */Date:/*10/28/2013 10:51:12 PM
>
> */To:/*m... */Subject:/*RE: [msp430] Problems with MSP430F2132
>
> Hi Al
>
> I put my program back to changing just the setting of TOS (0x400) and
> the fault returned. This is either not the fault or I have more than 1
> fault.
>
> Thanks
>
> Peter
>
> *From:*m...
> [mailto:m...] *On Behalf Of *Onestone
> *Sent:* Tuesday, 29 October 2013 12:45 PM
> *To:* m...
> *Subject:* Re: [msp430] Problems with MSP430F2132
>
> You're setting TOS (SP) to an odd number TOS should be end of RAM + 1,
> that is your bug here. so set it to 0X0400
>
> Al
>
> On 29/10/2013 1:46 PM, Peter Grey wrote:
>
> Hi Anthony
>
> I have solved my problem. In my program I setup the stack at RESET and
> then call a subroutine to set up the ports and the clock.
>
> Reset
>
> mov.w #3FFh,SP ; Initialize stackpointer
>
> call #Setup
>
> In Setup I then setup the clock
>
> clr.b &DCOCTL
>
> mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
>
> mov.b &CALDCO_16MHZ,&DCOCTL
>
> I then set up the port direction and initial states
>
> SetupP1 mov.b #0f3h,&P1DIR ; 11110011
>
> clr.b &P1OUT ; SET LOW
>
> bic.b #EN_BUZZER,&P1OUT ;turn off beeper
>
> bic.b #EN_30V,&P1OUT
>
> SetupP2 mov.b #0E8h,&P2DIR ;11101000,
>
> mov.b #07h,&P2SEL2 ;A0-A2
>
> clr.b &P2OUT
>
> bis.b #LIS_CS,&P2OUT
>
> clr.b MDA_COUNTER
>
> clr.b DURESS_COUNTER
>
> SetupP3 mov.b #0B0h,&P3DIR ;10110000
>
> clr.b &P3OUT
>
> bis.b #TR_SDI,&P3OUT
>
> bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
>
> Finally I do a ret
>
> My fix was to run this subroutine a second time and all my problems
> disappeared??
>
> Thanks
>
> Peter
>
> *From:*m...
> [mailto:m...] *On Behalf Of *a...@gmail.com
>
> *Sent:* Saturday, 26 October 2013 12:57 PM
> *To:* m...
> *Subject:* RE: [msp430] Problems with MSP430F2132
> Peter,
>
> I have just sent you an email that I explained something, but I don't
> know that is what you want. If you think part of your code has
> problem, you can zip that part and send it to me as an attachment file
> (txt file). I can read and have my opinion for you.
>
> Anthony Ha
>
> /-------Original Message-------/
>
> */From:/*Peter Grey */Date:/*10/25/2013 7:48:57 PM
>
> */To:/*m... */Subject:/*RE: [msp430] Problems with MSP430F2132
>
> Hi Anthony
>
> I can see what you are doing at RESET. It is similar to mine but I
> have a MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt
> (DOZE), I cannot see how you ever exit this. There is no RETI? What is
> the routine supposed to do apart from re-initialising the stack and
> setting up the registers again? I turn on a LED in the NMI interrupt
> routine but I never see this happen. I am beginning to think that this
> may not be a NMI problem, but something silly I am doing.
>
> Thanks
>
> Peter
>
> *From:*m...
> [mailto:m...] *On Behalf Of *a...@gmail.com
>
> *Sent:* Wednesday, 23 October 2013 11:40 AM
> *To:* m...
> *Subject:* RE: [msp430] Problems with MSP430F2132
>
> 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
>
> /-------Original Message-------/
>
> */From:/*Peter Grey */Date:/*10/22/2013 6:32:41 PM
>
> */To:/*m... */Subject:/*RE: [msp430] Problems with MSP430F2132
>
> 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
>
>
>
>
>
Content-Type: Text/Plain;
charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable
Al,
Sorry for my forgotten to put the RSEG CSTACK at the END of the
variables declanation.
;--------------------------------
; Variables definition:
;--------------------------------
RSEG DATA16_I
MDA_COUNTER DS 1 ; even address
DURESS_COUNTER DS 1 ; odd address
byte_var1 DS 1 ; even
address
byte_var2 DS 1 ; odd
address
word_var1 DS 2 ; even
address
word_var2 DS 4 ; even
address
....................................................
LAST_VARIABLE DS 1 ; .....
;-----------------
; The end of variables
;-----------------
RSEG CSTACK
DS 0
;--------------------
Now it should work for ALL MSP430 doesn't matter which one you are using. Be
carefull with odd or even address for byte or word. Byte can be odd or even,
but word has to be in even address.
Anthony Ha
-------Original Message-------
From: Onestone
Date: 10/29/2013 12:57:14 AM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
The problem with this is that in a pure assembler program CSTACK doesn't
exist, or you need to leave in elements of the compiler to leave it there
Al
On 29/10/2013 5:26 PM, a...@gmail.com wrote:
Peter,
As I said, use this code and you don't have to worry about what chip you are
using:
MOV.W #SFE(CSTACK),SP ;START OF STACK
Anthony
-------Original Message-------
From: Peter Grey
Date: 10/28/2013 11:44:07 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Anthony
The RAM for the F2132 is at 0x200 to 0x3FF.
Thanks for your help. I would like to spend a bit more time on this but I
have a few orders to get out and it is near the end of the month so
financial pressure is on. Please pardon the delays in getting back to you.
The other major difference between our code is that I use mov #0400h,SP
rather than mov.w #0400h,SP. As far as I can see this is exactly equivalent.
I have also tried other numbers such as 0x3fe but the error is the same.
I will clear up these orders first and then focus properly on this problem.
Cheers
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Tuesday, 29 October 2013 2:18 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
Try
MOV.W #SFE(CSTACK),SP ;START OF STACK
or
MOV.W #0300h,SP
START OF STACK
I don't remember exactly but 0400h doesn't work then it has to be #0300h,SP
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/28/2013 10:51:12 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al
I put my program back to changing just the setting of TOS (0x400) and the
fault returned. This is either not the fault or I have more than 1 fault.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
Onestone
Sent: Tuesday, 29 October 2013 12:45 PM
To: m...
Subject: Re: [msp430] Problems with MSP430F2132
You're setting TOS (SP) to an odd number TOS should be end of RAM + 1, that
is your bug here. so set it to 0X0400
Al
On 29/10/2013 1:46 PM, Peter Grey wrote:
Hi Anthony
I have solved my problem. In my program I setup the stack at RESET and then
call a subroutine to set up the ports and the clock.
Reset
mov.w #3FFh,SP ; Initialize
stackpointer
call #Setup
In Setup I then setup the clock
clr.b &DCOCTL
mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
mov.b &CALDCO_16MHZ,&DCOCTL
I then set up the port direction and initial states
SetupP1 mov.b #0f3h,&P1DIR ;
11110011
clr.b &P1OUT ; SET LOW
bic.b #EN_BUZZER,&P1OUT ;turn off beeper
bic.b #EN_30V,&P1OUT
SetupP2 mov.b #0E8h,&P2DIR ;11101000,
mov.b #07h,&P2SEL2 ;A0-A2
clr.b &P2OUT
bis.b #LIS_CS,&P2OUT
clr.b MDA_COUNTER
clr.b DURESS_COUNTER
SetupP3 mov.b #0B0h,&P3DIR ;10110000
clr.b &P3OUT
bis.b #TR_SDI,&P3OUT
bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
Finally I do a ret
My fix was to run this subroutine a second time and all my problems
disappeared??
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Saturday, 26 October 2013 12:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Peter,
I have just sent you an email that I explained something, but I don't know
that is what you want. If you think part of your code has problem, you can
zip that part and send it to me as an attachment file (txt file). I can read
and have my opinion for you.
Anthony Ha
-------Original Message-------
From: Peter Grey
Date: 10/25/2013 7:48:57 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Anthony
I can see what you are doing at RESET. It is similar to mine but I have a
MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
see how you ever exit this. There is no RETI? What is the routine supposed
to do apart from re-initialising the stack and setting up the registers
again? I turn on a LED in the NMI interrupt routine but I never see this
happen. I am beginning to think that this may not be a NMI problem, but
something silly I am doing.
Thanks
Peter
From: m... [mailto:m...] On Behalf Of
a...@gmail.com
Sent: Wednesday, 23 October 2013 11:40 AM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
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
-------Original Message-------
From: Peter Grey
Date: 10/22/2013 6:32:41 PM
To: m...
Subject: RE: [msp430] Problems with MSP430F2132
Hi Al,
Thanks for the detailed reply. I must admit I have not used NMI since I was
using the PDP minis, 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
--------------Boundary-00=_QHQFWCW0000000000000
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
 Al,  Sorry for my forgotten to put the
RSEGÂ Â Â Â Â Â CSTACK at the END of the variables
declanation. Â ;-------------------------------- ; Variables definition:
;-------------------------------- Â Â Â Â Â Â Â Â Â Â Â Â
      RSEG  Â
         DATA16_I  MDA_COUNTER         Â
DSÂ Â Â 1Â Â Â Â Â Â Â Â Â
         ; even address DURESS_COUNTER     DS  Â
1Â Â Â Â Â Â Â Â Â Â Â Â
      ; odd address byte_var1        Â
           Â
DSÂ Â 1Â Â Â Â Â Â Â Â Â
         ; even address byte_var2        Â
           Â
DSÂ Â 1Â Â Â Â Â Â Â Â Â
         ; odd address word_var1                           DSÂ
2Â Â Â Â Â Â Â Â Â Â Â Â
      ; even address word_var2        Â
            DS
4Â Â Â Â Â Â Â Â Â Â Â Â
      ; even address .................................................... LAST_VARIABLE        Â
DSÂ Â Â 1Â Â Â Â Â Â Â Â Â
         ; .....  ;----------------- ; The end of variables ;-----------------                       Â
RSEGÂ Â Â Â Â Â Â Â Â
  Â
CSTACK Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â DSÂ Â Â Â Â 0Â ;--------------------Â Â Now it should work for ALL MSP430
doesn't matter which one you are using. Be carefull with odd or even
address for byte or word. Byte can be odd or even, but word has to be in even
address.  Anthony Ha   -------Original Message-------  From: Onestone Date: 10/29/2013 12:57:14
AM To: m... Subject: Re: [msp430]
Problems with MSP430F2132 Â The problem with this is that in a pure assembler program
CSTACK doesn't exist, or you need to leave in elements of the compiler to
leave it thereAl On 29/10/2013 5:26 PM, a...@gmail.com
wrote:
|
I might be barking up the wrong tree here but I don't see you setting up the BOR.
If you have a slow supply ramp up at startup, the DCO will happliy start up at 16Mhz, but as soon as you switch the CPU to run off the DCO, if the supply is not high enough it will crash dismally.
Each device datasheet has a graph which depicts the voltage vs frequency and AFAIK the device you are using needs at least 3V to run at 16Mhz.
Things to try:
Make your reset time constant longer to avoid slow supply ramp-up.
Add extra delay before setting DCO.
Set the BOR voltage to the voltage required at the desired frequency from the device graph and wait for the status bit before setting DCO.
Regards
Steve
--- In m..., "anthonyha2011@..." wrote:
> Al,
>
> Sorry for my forgotten to put the RSEG CSTACK at the END of the
> variables declanation.
>
> ;--------------------------------
> ; Variables definition:
> ;--------------------------------
> RSEG DATA16_I
>
> MDA_COUNTER DS 1 ; even address
> DURESS_COUNTER DS 1 ; odd address
> byte_var1 DS 1 ; even
> address
> byte_var2 DS 1 ; odd
> address
> word_var1 DS 2 ; even
> address
> word_var2 DS 4 ; even
> address
> ....................................................
> LAST_VARIABLE DS 1 ; .....
>
> ;-----------------
> ; The end of variables
> ;-----------------
> RSEG CSTACK
> DS 0
> ;--------------------
>
> Now it should work for ALL MSP430 doesn't matter which one you are using. Be
> carefull with odd or even address for byte or word. Byte can be odd or even,
> but word has to be in even address.
>
> Anthony Ha
>
>
> -------Original Message-------
>
> From: Onestone
> Date: 10/29/2013 12:57:14 AM
> To: m...
> Subject: Re: [msp430] Problems with MSP430F2132
>
> The problem with this is that in a pure assembler program CSTACK doesn't
> exist, or you need to leave in elements of the compiler to leave it there
>
> Al
>
> On 29/10/2013 5:26 PM, anthonyha2011@... wrote:
>
> Peter,
>
> As I said, use this code and you don't have to worry about what chip you are
> using:
>
> MOV.W #SFE(CSTACK),SP ;START OF STACK
>
>
> Anthony
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/28/2013 11:44:07 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Anthony
> The RAM for the F2132 is at 0x200 to 0x3FF.
>
> Thanks for your help. I would like to spend a bit more time on this but I
> have a few orders to get out and it is near the end of the month so
> financial pressure is on. Please pardon the delays in getting back to you.
> The other major difference between our code is that I use mov #0400h,SP
> rather than mov.w #0400h,SP. As far as I can see this is exactly equivalent.
> I have also tried other numbers such as 0x3fe but the error is the same.
> I will clear up these orders first and then focus properly on this problem.
>
> Cheers
>
> Peter
>
> From: m... [mailto:m...] On Behalf Of
> anthonyha2011@...
> Sent: Tuesday, 29 October 2013 2:18 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Peter,
>
> Try
>
> MOV.W #SFE(CSTACK),SP ;START OF STACK
> or
>
> MOV.W #0300h,SP
> START OF STACK
> I don't remember exactly but 0400h doesn't work then it has to be #0300h,SP
>
> Anthony Ha
>
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/28/2013 10:51:12 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Hi Al
>
> I put my program back to changing just the setting of TOS (0x400) and the
> fault returned. This is either not the fault or I have more than 1 fault.
>
> Thanks
>
> Peter
>
>
> From: m... [mailto:m...] On Behalf Of
> Onestone
> Sent: Tuesday, 29 October 2013 12:45 PM
> To: m...
> Subject: Re: [msp430] Problems with MSP430F2132
>
> You're setting TOS (SP) to an odd number TOS should be end of RAM + 1, that
> is your bug here. so set it to 0X0400
>
> Al
> On 29/10/2013 1:46 PM, Peter Grey wrote:
> Hi Anthony
>
> I have solved my problem. In my program I setup the stack at RESET and then
> call a subroutine to set up the ports and the clock.
> Reset
> mov.w #3FFh,SP ; Initialize
> stackpointer
> call #Setup
> In Setup I then setup the clock
> clr.b &DCOCTL
> mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
> mov.b &CALDCO_16MHZ,&DCOCTL
> I then set up the port direction and initial states
> SetupP1 mov.b #0f3h,&P1DIR ;
> 11110011
> clr.b &P1OUT ; SET LOW
> bic.b #EN_BUZZER,&P1OUT ;turn off beeper
> bic.b #EN_30V,&P1OUT
>
> SetupP2 mov.b #0E8h,&P2DIR ;11101000,
> mov.b #07h,&P2SEL2 ;A0-A2
> clr.b &P2OUT
> bis.b #LIS_CS,&P2OUT
> clr.b MDA_COUNTER
> clr.b DURESS_COUNTER
>
> SetupP3 mov.b #0B0h,&P3DIR ;10110000
> clr.b &P3OUT
> bis.b #TR_SDI,&P3OUT
> bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both high
> Finally I do a ret
> My fix was to run this subroutine a second time and all my problems
> disappeared??
>
> Thanks
>
> Peter
> From: m... [mailto:m...] On Behalf Of
> anthonyha2011@...
> Sent: Saturday, 26 October 2013 12:57 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Peter,
>
> I have just sent you an email that I explained something, but I don't know
> that is what you want. If you think part of your code has problem, you can
> zip that part and send it to me as an attachment file (txt file). I can read
> and have my opinion for you.
>
> Anthony Ha
>
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/25/2013 7:48:57 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Hi Anthony
>
> I can see what you are doing at RESET. It is similar to mine but I have a
> MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I cannot
> see how you ever exit this. There is no RETI? What is the routine supposed
> to do apart from re-initialising the stack and setting up the registers
> again? I turn on a LED in the NMI interrupt routine but I never see this
> happen. I am beginning to think that this may not be a NMI problem, but
> something silly I am doing.
>
> Thanks
>
> Peter
>
> From: m... [mailto:m...] On Behalf Of
> anthonyha2011@...
> Sent: Wednesday, 23 October 2013 11:40 AM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
>
> 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
>
>
>
>
>
>
>
>
>
>
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/22/2013 6:32:41 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> 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
>
Yahoo Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/msp430/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/msp430/join
(Yahoo! ID required)
<*> To change settings via email:
m...
m...
<*> To unsubscribe from this group, send an email to:
m...
<*> Your use of Yahoo Groups is subject to:
http://info.yahoo.com/legal/us/yahoo/utos/terms/
I have not set up the BOR. Also I changed the DCO to 1MHz later and it made
no difference. I shall setup the SVS register and see the results
Thanks
Peter
-----Original Message-----
From: m... [mailto:m...] On Behalf Of
stephen.dyble
Sent: Tuesday, 5 November 2013 4:44 AM
To: m...
Subject: [msp430] Re: Problems with MSP430F2132
Hi there
I might be barking up the wrong tree here but I don't see you setting up the
BOR.
If you have a slow supply ramp up at startup, the DCO will happliy start up
at 16Mhz, but as soon as you switch the CPU to run off the DCO, if the
supply is not high enough it will crash dismally.
Each device datasheet has a graph which depicts the voltage vs frequency and
AFAIK the device you are using needs at least 3V to run at 16Mhz.
Things to try:
Make your reset time constant longer to avoid slow supply ramp-up.
Add extra delay before setting DCO.
Set the BOR voltage to the voltage required at the desired frequency from
the device graph and wait for the status bit before setting DCO.
Regards
Steve
--- In m..., "anthonyha2011@..."
wrote:
> Al,
>
> Sorry for my forgotten to put the RSEG CSTACK at the END of the
> variables declanation.
>
> ;--------------------------------
> ; Variables definition:
> ;--------------------------------
> RSEG DATA16_I
>
> MDA_COUNTER DS 1 ; even address
> DURESS_COUNTER DS 1 ; odd address
> byte_var1 DS 1 ; even
> address
> byte_var2 DS 1 ; odd
> address
> word_var1 DS 2 ; even
> address
> word_var2 DS 4 ; even
> address
> ....................................................
> LAST_VARIABLE DS 1 ; .....
>
> ;-----------------
> ; The end of variables
> ;-----------------
> RSEG CSTACK
> DS 0
> ;--------------------
>
> Now it should work for ALL MSP430 doesn't matter which one you are
> using. Be carefull with odd or even address for byte or word. Byte can
> be odd or even, but word has to be in even address.
>
> Anthony Ha
>
>
> -------Original Message-------
>
> From: Onestone
> Date: 10/29/2013 12:57:14 AM
> To: m...
> Subject: Re: [msp430] Problems with MSP430F2132
>
> The problem with this is that in a pure assembler program CSTACK
> doesn't exist, or you need to leave in elements of the compiler to
> leave it there
>
> Al
>
> On 29/10/2013 5:26 PM, anthonyha2011@... wrote:
>
> Peter,
>
> As I said, use this code and you don't have to worry about what chip
> you are
> using:
>
> MOV.W #SFE(CSTACK),SP ;START OF
STACK
>
>
> Anthony
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/28/2013 11:44:07 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Anthony
> The RAM for the F2132 is at 0x200 to 0x3FF.
>
> Thanks for your help. I would like to spend a bit more time on this
> but I have a few orders to get out and it is near the end of the month
> so financial pressure is on. Please pardon the delays in getting back to
you.
> The other major difference between our code is that I use mov
> #0400h,SP rather than mov.w #0400h,SP. As far as I can see this is exactly
equivalent.
> I have also tried other numbers such as 0x3fe but the error is the same.
> I will clear up these orders first and then focus properly on this
problem.
>
> Cheers
>
> Peter
>
> From: m... [mailto:m...] On Behalf
> Of anthonyha2011@...
> Sent: Tuesday, 29 October 2013 2:18 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Peter,
>
> Try
>
> MOV.W #SFE(CSTACK),SP ;START OF
STACK
> or
>
> MOV.W #0300h,SP
> START OF STACK
> I don't remember exactly but 0400h doesn't work then it has to be
> #0300h,SP
>
> Anthony Ha
>
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/28/2013 10:51:12 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Hi Al
>
> I put my program back to changing just the setting of TOS (0x400) and
> the fault returned. This is either not the fault or I have more than 1
fault.
>
> Thanks
>
> Peter
>
>
> From: m... [mailto:m...] On Behalf
> Of Onestone
> Sent: Tuesday, 29 October 2013 12:45 PM
> To: m...
> Subject: Re: [msp430] Problems with MSP430F2132
>
> You're setting TOS (SP) to an odd number TOS should be end of RAM + 1,
> that is your bug here. so set it to 0X0400
>
> Al
> On 29/10/2013 1:46 PM, Peter Grey wrote:
> Hi Anthony
>
> I have solved my problem. In my program I setup the stack at RESET and
> then call a subroutine to set up the ports and the clock.
> Reset
> mov.w #3FFh,SP ; Initialize
> stackpointer
> call #Setup
> In Setup I then setup the clock
> clr.b &DCOCTL
> mov.b &CALBC1_16MHZ,&BCSCTL1 ; Set DCO to 8MHz
> mov.b &CALDCO_16MHZ,&DCOCTL
> I then set up the port direction and initial states
> SetupP1 mov.b #0f3h,&P1DIR ;
> 11110011
> clr.b &P1OUT ; SET LOW
> bic.b #EN_BUZZER,&P1OUT ;turn off
beeper
> bic.b #EN_30V,&P1OUT
>
> SetupP2 mov.b #0E8h,&P2DIR ;11101000,
> mov.b #07h,&P2SEL2 ;A0-A2
> clr.b &P2OUT
> bis.b #LIS_CS,&P2OUT
> clr.b MDA_COUNTER
> clr.b DURESS_COUNTER
>
> SetupP3 mov.b #0B0h,&P3DIR ;10110000
> clr.b &P3OUT
> bis.b #TR_SDI,&P3OUT
> bis.b #nSS_CONF+nSS_DATA,&P3OUT ;set both
high
> Finally I do a ret
> My fix was to run this subroutine a second time and all my problems
> disappeared??
>
> Thanks
>
> Peter
> From: m... [mailto:m...] On Behalf
> Of anthonyha2011@...
> Sent: Saturday, 26 October 2013 12:57 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Peter,
>
> I have just sent you an email that I explained something, but I don't
> know that is what you want. If you think part of your code has
> problem, you can zip that part and send it to me as an attachment file
> (txt file). I can read and have my opinion for you.
>
> Anthony Ha
>
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/25/2013 7:48:57 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> Hi Anthony
>
> I can see what you are doing at RESET. It is similar to mine but I
> have a
> MSP430F2132 and am using DCO at 1MHz. In the NMI interrupt (DOZE), I
> cannot see how you ever exit this. There is no RETI? What is the
> routine supposed to do apart from re-initialising the stack and
> setting up the registers again? I turn on a LED in the NMI interrupt
> routine but I never see this happen. I am beginning to think that this
> may not be a NMI problem, but something silly I am doing.
>
> Thanks
>
> Peter
>
> From: m... [mailto:m...] On Behalf
> Of anthonyha2011@...
> Sent: Wednesday, 23 October 2013 11:40 AM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
>
> 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
>
>
>
>
>
>
>
>
>
>
>
>
>
> -------Original Message-------
>
> From: Peter Grey
> Date: 10/22/2013 6:32:41 PM
> To: m...
> Subject: RE: [msp430] Problems with MSP430F2132
>
> 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
>
Yahoo Groups Links
Yahoo Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/msp430/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/msp430/join
(Yahoo! ID required)
<*> To change settings via email:
m...
m...
<*> To unsubscribe from this group, send an email to:
m...
<*> Your use of Yahoo Groups is subject to:
http://info.yahoo.com/legal/us/yahoo/utos/terms/