Reply by pseudo_ral March 6, 20122012-03-06
Thank you Paul

Most appreciated, code now running correctly (after a change to Two_Sec_Count DS16 1 which I think / hope is right).

Many thanks (and for saving life).

Regards
Ralph

Beginning Microcontrollers with the MSP430

Reply by Onestone March 6, 20122012-03-06
In IAR VIEW->registers

Al

On 7/03/2012 2:06 AM, pseudo_ral wrote:
> Thank you David, a concise, clear response.
>
> I had thought just extending Two-Sec_Count to 2 bytes (which I thought was Two_Sec_Count DS 2) or more would go some way to solving the limitation but it made no difference.
>
> I would love to be able to monitor R12 and others but IAR doesn't seem to allow me to do that (attempts to add it to Watch are unsuccessful).
>
> I have made contact with the original developer who may be able to assist later today (I am no developer as you can probably tell).
>
> Thank you again.
>
> Regards
> Ralph
>
>
Reply by Onestone March 6, 20122012-03-06
How would you know that they draw the lowest current possible. I can
guarantee that they don't. they couldn't possibly do so with this set
up. Sorry, but you misunderstand the code to the point that you can't
make a valid assesment of it's function. There are far simpler ways of
doing what you are trying to do here. For starters unless you are using
nested interrupts why compromise an ISR with a PUSH and POP every time?
why not simply dedicate a register for interrupt use only? No matter how
well valued a contributor is they sometimes get it wrong, as I did
regarding the byte counter, so too has this guy:-

Timer_Overflow
PUSH R12 ;3clks, preserve register
MOV.B&Two_Sec_Count,R12 ;3clks move counter to register
INC R12 ;1clk increment count
CMP #MULTIPLE,R12 ;2clks,has it reached delay period yet
JNE Not_flag ;2clks if not skip to end
BIS #TIMER_OVERFLOW,&System_Flags ;5clks if ended set flag
CLR R12 ;1clk and clear register
Not_flag
MOV.B R12,&Two_Sec_Count ;4clks return register to counter
POP R12 ;2clks recover original register
BIC #0xF0,0(SP) ;5clks clear sleep state
RETI
That's 28 clock cycles not including the interrup latency and RETI, when
all you really need to do, since you exit sleep mode every time is:-

Timer_Overflow
DEC &Two_Sec_Count ;4clks
BIC #LPM4,0(SP) ;5clks clear sleep state
RETI

Then in main all you need to is check the counter for 0, if it is zero then do whatever and then reload the counter to MULTIPLE. However you can improve on this even more. The way the ISR is currently written it exits sleep mode every time it is called, yet it seems that the real action takes place after some accumulated number of overflows. In which case you can cut power consumption even more by simply not exiting sleep mode until you need to
Timer_Overflow
DEC &Two_Sec_Count ;4clks
JNZ snooze ;2clks
BIC #LPM4,0(SP) ;5clks clear sleep state
snooze:
RETI

The first example reduces time in the ISR to 1/3 the original, whereas the second reduces it to around 40% the original time, BUT reduces the amount of time spent in active mode in the main loop by MULTIPLE - 1 times.

Damn, I've probably just doubled your battery life.

Al
On 7/03/2012 1:24 AM, pseudo_ral wrote:
> Thank you for your prompt responses and whilst I appreciate your comments our products based on this code have been working fine for seven years, draw the lowest current possible, deliberately sit in a 'non-productive loop' and multiple timers are already in use elsewhere in the code.
>
> However as I have already pointed out I struggle to understand code (though this code was originally produced by a person who was a highly valued contributor to this group).
>
> My question is why does it work up to a PERIOD set to 400 (seconds) but no higher?
>
> I have included (below) some of the interrupt vector and start bit interrupts;
>
> Regards
> Ralph
>
> COMMON INTVEC
> DS 6
> DS 2
> DS 8
> DW Timer_A1_Interrupt
> DW Timer_A0_Interrupt
>
> RSEG DATA16_Z
>
> Two_Sec_Count DS 1
>
> RSEG CODE
>
> TIMER_OVERFLOW EQU 1
>
> Timer_A1_Interrupt
> ADD.W&TAIV,PC
> RETI
> JMP Timer_Module_1
> JMP Timer_Module_2
> JMP Timer_Module_3
> JMP Timer_Module_4
> JMP Timer_Overflow
> JMP Timer_Reserved_1
> JMP Timer_Reserved_2
>
> Timer_Module_2
> BIS #SEARCH_TIME_EXPIRED,&System_Flags
> ;;_Finished
> BIC #0xF0,0(SP) RETI
>
> Timer_Module_3
> Timer_Module_4
>
Reply by Onestone March 6, 20122012-03-06
It doesn't need a loop if it exits from sleep mode to main code.
Normally the main code would re-assert the sleep situation, the timer
overflows again, forcing the interrupt condition. the loop is implicit.
however i did miss the byte storage. believe it or not I actually looked
for it! that's what 3 hours kip in 2 days does for you!

Al

On 7/03/2012 1:10 AM, Paul Curtis wrote:
>> It appears that the intent is for this code to interrupt on timer
> overflow,
>> then hang in the ISR until some delay has past before waking up. WHY? why
> not
>> simply extend the sleep period, or why not trigger a second timer to force
> the
>> delay if you really need a second period of time?
> There's no loop in the code, it seems to be straight line with a conditional
> kink. However, the guy is using byte storage and comparing to 400. Yeah.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> SolderCore running Defender... http://www.vimeo.com/25709426
>
>
Reply by "Redd, Emmett R" March 6, 20122012-03-06
What do you mean it is not big enough? R12 is 16 bits (as are all but 2 MSP 430 registers, PC and SP, although they are addressed as 16 bits (Have any versions implemented the reserved bits in SR?)).

Emmett Redd, Ph.D., Professor mailto:E...@MissouriState.Edu
Physics, Astronomy, and Materials Science Office: 417-836-5221
Missouri State University Dept: 417-838-5131
901 S NATIONAL AVENUE FAX: 417-836-6226
SPRINGFIELD, MO 65897 USA Lab: 417-836-3770

It is clear that thought is not free if the profession of certain opinions make it impossible to earn a living. -- Bertrand Russel

> -----Original Message-----
> From: m... [mailto:m...] On Behalf
> Of pseudo_ral
> Sent: Tuesday, March 06, 2012 9:54 AM
> To: m...
> Subject: [msp430] Re: Interrupter not working
>
> Thanks Paul
>
> R12 is clearly not going to be large enough to store the count I
> require (800 secs) so I will wait for assistance later today.
>
> Thank you again.
> Ralph
>
>
Reply by Paul Curtis March 6, 20122012-03-06
> R12 is clearly not going to be large enough to store the count I require
(800
> secs) so I will wait for assistance later today.

R12 is an internal 16-bit register and it *is* big enough. The problem is
you are using the '.B' suffix, to store a BYTE, which can only be between 0
and 255. Hence, MOV.B x, R12 can never make R12 greater than 255. You will
need to use a .W extension and change the data reservation appropriately.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore running Defender... http://www.vimeo.com/25709426



Reply by pseudo_ral March 6, 20122012-03-06
Thanks Paul

R12 is clearly not going to be large enough to store the count I require (800 secs) so I will wait for assistance later today.

Thank you again.
Ralph

Reply by Paul Curtis March 6, 20122012-03-06
> I would love to be able to monitor R12 and others but IAR doesn't seem to
> allow me to do that (attempts to add it to Watch are unsuccessful).

You look at it in the Registers window...
>
> I have made contact with the original developer who may be able to assist
> later today (I am no developer as you can probably tell).
>
> Thank you again.
>
> Regards
> Ralph
>
>
Reply by pseudo_ral March 6, 20122012-03-06
Thank you David, a concise, clear response.

I had thought just extending Two-Sec_Count to 2 bytes (which I thought was Two_Sec_Count DS 2) or more would go some way to solving the limitation but it made no difference.

I would love to be able to monitor R12 and others but IAR doesn't seem to allow me to do that (attempts to add it to Watch are unsuccessful).

I have made contact with the original developer who may be able to assist later today (I am no developer as you can probably tell).

Thank you again.

Regards
Ralph

Reply by "David W. Schultz" March 6, 20122012-03-06
On 03/06/2012 08:54 AM, pseudo_ral wrote:
> My question is why does it work up to a PERIOD set to 400 (seconds) but no higher?
>

The value stored at Two_Sec_Count is always in the range of 0 to 255
(0x00 to 0xff) as is usual for bytes. If you want to represent larger
numbers you must use more bits.

--
David W. Schultz
http://home.earthlink.net/~david.schultz
"Who? What? Where? When? Aahhhg!" - Duck Dodgers