Searching \ for '[PIC]: coding challenge: await' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'coding challenge: await'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: coding challenge: await'
2003\02\27@023348 by Wouter van Ooijen

face picon face
coding challenge:

- 14-bit core PIC
- forget about paging and banking issues
- smallest possible code
- assembler

TMR1 is a free-running 16-bit timer that can be read as two file
registers TMR1H and TMR1L. Note that there is no buffering in the
reading, so for 00FF you might read FF as low byte and then 01 as high
byte (just after the rollover).

I have two file register bytes tH and tL that represent a TMR1 value
that lies in the future. I want to wait until this 'moment' has arrived
(or passed). Note that due to the above reading problem, the possibility
of interrupts and one more issue (think for yourself) it is no use to
loop and wait for a 'perfect match'. Looking for (tH,tL) >=
(TMR1H,TMR1L) won't do either, because the tH,tL 'moment' might be
beyond a roll-over from FFFF to 0000.

Note that there are actually two challenges: first find a suitable
algorithm, then encode it in assembler.

The application of such code is to create a timing loop with zero
cumulative error.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@035125 by Werner Soekoe

flavicon
face
Wouter,

I assume Timer1 causes an Interrupt when it rolls over from 0xFFFF to
0x0000. Why don't you use the timer, lets say you want to count 0x02FF
cycles. Deduct that from 0xFFFF to get 0xFD00. Write that to Timer1, and
wait for the interrupt to occur 0x02FF counts later?

I have read the PIC16F62x's datasheet on Timer1, and even though you might
be using a different chip, the operation should still be the same. So my
first bet is to preset the TMR1H and TMR1L values and wait for the overflow
Interrupt.

An alternative, which I doubt will be suitable for your application, is to
have a slower external clock pulsing Timer1. Run Timer1 in counter mode, and
use a clock source of at least CPU-Freq / 20, then a looped test algorythm
might work.

Hope this helps somewhat.

Cheers
Werner


{Original Message removed}

2003\02\27@035829 by Wouter van Ooijen

face picon face
> I assume Timer1 causes an Interrupt when it rolls over from 0xFFFF to
> 0x0000. Why don't you use the timer, lets say you want to count 0x02FF
> cycles. Deduct that from 0xFFFF to get 0xFD00. Write that to
> Timer1, and
> wait for the interrupt to occur 0x02FF counts later?

I don't want to use interrupts, and I don't want to fiddle with the
timer, except from assuring that it runs. arguments:
- I want to be able to use two or more such await-delays independently
- the timer and associated interrupt must still be available for other
uses

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@040703 by hael Rigby-Jones

picon face
> -----Original Message-----
> From: Wouter van Ooijen [SMTP:spam_OUTwouterTakeThisOuTspamVOTI.NL]
> Sent: Thursday, February 27, 2003 8:57 AM
> To:   .....PICLISTKILLspamspam@spam@MITVMA.MIT.EDU
> Subject:      Re: [PIC]: coding challenge: await
>
> > I assume Timer1 causes an Interrupt when it rolls over from 0xFFFF to
> > 0x0000. Why don't you use the timer, lets say you want to count 0x02FF
> > cycles. Deduct that from 0xFFFF to get 0xFD00. Write that to
> > Timer1, and
> > wait for the interrupt to occur 0x02FF counts later?
>
> I don't want to use interrupts, and I don't want to fiddle with the
> timer, except from assuring that it runs. arguments:
> - I want to be able to use two or more such await-delays independently
> - the timer and associated interrupt must still be available for other
> uses
>
> Wouter van Ooijen
>
And I guess you don't want to use or don't have the CCP module?

Mike


=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
Any questions about Bookham's E-Mail service should be directed to postmasterspamKILLspambookham.com.

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@040830 by Vasile Surducan

flavicon
face
Wouter, I'm not a women's dream in pic assembling, but I think
this problem can be solved in the same manner like Roman Black and
Dwaine Reid ? ( using Bob's Ammerman ? ideea ) have done it using
a three bytes representation for clock frequency and the tmr0.
For a free running tmr1, I think will be problems in reading the tmr1l and
tmr1h values for comparison with a constant ( or a variable ).

friendly,
Vasile


On Thu, 27 Feb 2003, Wouter van Ooijen wrote:

{Quote hidden}

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@042929 by Werner Soekoe

flavicon
face
Wouter,

I'm sorry, but I don't have any other ideas. Have you ever considered that
you're possibly trying to squueze too much from one PIC? :-)

Hoping you find a solution

Werner

{Quote hidden}

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@043357 by Stuart Meier

flavicon
picon face
Werner

It's a "Coding Challenge" - I am sure Wouter KNOWS a solution :-) ... but can
someone not just find one but better his?

Stuart
{Original Message removed}

2003\02\27@073136 by Wouter van Ooijen

face picon face
> It's a "Coding Challenge" - I am sure Wouter KNOWS a solution
> :-) ... but can someone not just find one but better his?

Of course there is a solution. Reading a 2-byte timer is a standard
trick and it is in the datsheet too, and comparing 16-bit numbers is no
rocket science either.

But this morning I had not realy worked out a solution, I was probably
trying to do too much. With the added constraint that the moment we are
waiting for is less than a most significant bit of the timer in the
future, I think I have a 10-instruction solution.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@075908 by Olin Lathrop

face picon face
> I have two file register bytes tH and tL that represent a TMR1 value
> that lies in the future. I want to wait until this 'moment' has arrived
> (or passed).

Why not use a CCP module in compare mode, or is that cheating for some
reason?  (Doesn't sound like a cheat to me if it gets the job done).


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@080909 by Wouter van Ooijen

face picon face
> > I have two file register bytes tH and tL that represent a TMR1 value
> > that lies in the future. I want to wait until this 'moment'
> has arrived
> > (or passed).
>
> Why not use a CCP module in compare mode, or is that cheating for some
> reason?  (Doesn't sound like a cheat to me if it gets the job done).

That would be the preferred way for *one* active interval at a time, but
I would like to have more than one, for instance for both timekeeping
and asynchronous sending. And it ties up a hardware resource that is
usefull for other things.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@083815 by Roman Black

flavicon
face
Wouter van Ooijen wrote:
>
> > It's a "Coding Challenge" - I am sure Wouter KNOWS a solution
> > :-) ... but can someone not just find one but better his?
>
> Of course there is a solution. Reading a 2-byte timer is a standard
> trick and it is in the datsheet too,


Unfortunately the datasheet "solution" for reading
a 2byte timer is most dissatisfying. From memory,
doesn't it go something like:
* read the timer
* if it's a catastrophy, read it again
??
:o)
-Roman

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@085058 by michael brown

picon face
----- Original Message -----
From: "Roman Black" <.....fastvidKILLspamspam.....EZY.NET.AU>
To: <EraseMEPICLISTspam_OUTspamTakeThisOuTMITVMA.MIT.EDU>
Sent: Thursday, February 27, 2003 7:27 AM
Subject: Re: [PIC]: coding challenge: await


{Quote hidden}

Of course there is always the extremely satisfying alternative:

* stop the timer
* read the timer
* start the timer

;-)

I suppose that you could use the Rube Goldberg approach:

tie output pin to input of capture port
toggle pin
read capture registers

Now isn't that all better?  ;-)

Since this is such a common issue, you'd think that they would just
create a SNAP instruction to capture the timer into a separate SFR.

michael brown

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@092041 by Werner Soekoe

flavicon
face
> Since this is such a common issue, you'd think that they would just
> create a SNAP instruction to capture the timer into a separate SFR.

Stil, even if you SNAP the values, compare it, SNAP again, compare etc. you
will still miss some counts due to the time it takes to compare the values.
Lets say you're looking for 0x01ff, you SNAP it while at 0x01FA, compare it
(10 clock cycles for example), you next SNAP will be at around 0x204, which
means you'll completely miss 0x01ff.

I really, and honestly don't think there is an easy answer for this one.

Werner

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@093053 by michael brown

picon face
From: "Werner Soekoe" <WernerSspamspam_OUTFSL.GOV.ZA>

> > Since this is such a common issue, you'd think that they would just
> > create a SNAP instruction to capture the timer into a separate SFR.
>
> Stil, even if you SNAP the values, compare it, SNAP again, compare
etc. you
> will still miss some counts due to the time it takes to compare the
values.
> Lets say you're looking for 0x01ff, you SNAP it while at 0x01FA,
compare it
> (10 clock cycles for example), you next SNAP will be at around 0x204,
which
> means you'll completely miss 0x01ff.
>
> I really, and honestly don't think there is an easy answer for this
one.

I certainly don't disagree with what you are saying, but a SNAP would be
the most efficient way to sample the 16 bit timer value.

In the case of a timer incrementing every clock cycle, there is no way
(that I know of) that any sort of coded comparison is going to guarantee
that you could look for a specific value, you will have to look for a  >
condition, as you clearly indicated.  The only way to do that is to use
the capture feature and find out about it after the fact by checking the
int flag, or using an actual int routine.  In both of those cases, you
will still find out about it after the fact.

michael brown

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@093252 by Wouter van Ooijen

face picon face
> Unfortunately the datasheet "solution" for reading
> a 2byte timer is most dissatisfying. From memory,
> doesn't it go something like:
> * read the timer
> * if it's a catastrophy, read it again

That is a way to describe it, but what is wrong with that?

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@094303 by michael brown

picon face
Wouter van Ooijen wrote:
>> Unfortunately the datasheet "solution" for reading
>> a 2byte timer is most dissatisfying. From memory,
>> doesn't it go something like:
>> * read the timer
>> * if it's a catastrophy, read it again
>
> That is a way to describe it, but what is wrong with that?

Jitter?  If you're using the timer to measure the length of something,
this will introduce a level of uncertainty that may have been avoided by
using the capture feature (or my SNAP© idea  ;-)  IMO, it all depends
upon the application and whether this uncertainty is acceptable or not.
Any attempt to correct the uncertainty introduces more uncertainty,
either by taking more time to get the correct value, or more delay for
the following code.

michael brown

"In the land of the blind, he who has one eye is king"

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@095151 by Spehro Pefhany

picon face
At 07:43 AM 2/27/2003 -0600, you wrote:

>Since this is such a common issue, you'd think that they would just
>create a SNAP instruction to capture the timer into a separate SFR.

Some micros have a single buffer byte that captures one of the two
bytes. When you read one byte (say the lower byte), the other byte
(say the upper byte) is captured and latched at the same instant.
You can then read the buffer byte at your leisure. So no new
instruction is necessary.

Best regards,

Spehro Pefhany --"it's the network..."            "The Journey is the reward"
@spam@speffKILLspamspaminterlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@100829 by Roman Black

flavicon
face
Wouter van Ooijen wrote:
>
> > Unfortunately the datasheet "solution" for reading
> > a 2byte timer is most dissatisfying. From memory,
> > doesn't it go something like:
> > * read the timer
> > * if it's a catastrophy, read it again
>
> That is a way to describe it, but what is wrong with that?



Because two superior methods immediately spring to
mind;

microchip's method;
* do job
* if it fails, do it again

better method A;
* do job
* if it fails, fix it

better method B;
* check before doing the job
* do it once, properly

for an example of better method A, how's this;
* get LO, store it (critical timer read)
* get HI (2 cycles since we got LO)
* if LO is FE or FF; dec HI
which is possibly the best method. :o)
-Roman

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@101455 by Wouter van Ooijen

face picon face
> I think I have a 10-instruction solution.

That was too optimistic, I think 15 might be more like it. Still
struggling. No other takers?

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@101925 by Wouter van Ooijen

face picon face
> for an example of better method A, how's this;
> * get LO, store it (critical timer read)
> * get HI (2 cycles since we got LO)
> * if LO is FE or FF; dec HI

What about an interrupt between reading Lo and Hi? And maybe the timer
is running with a prescaler, so Lo = FE or FF does not imply that a
carry will occur as soon as you assume.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@102142 by Olin Lathrop

face picon face
> Stil, even if you SNAP the values, compare it, SNAP again, compare etc.
> you will still miss some counts due to the time it takes to compare the
> values. Lets say you're looking for 0x01ff, you SNAP it while at
> 0x01FA, compare it (10 clock cycles for example), you next SNAP will be
> at around 0x204, which means you'll completely miss 0x01ff.
>
> I really, and honestly don't think there is an easy answer for this one.

You can look at the timer and decide when your close, then jump indexed
into sequential NOPs to burn up exactly the remaining time until the timer
would reach the trigger value.  I've done this in a 12C508A that had to
produce some fixed frequencies without any jitter.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@102555 by Olin Lathrop

face picon face
> Some micros have a single buffer byte that captures one of the two
> bytes. When you read one byte (say the lower byte), the other byte
> (say the upper byte) is captured and latched at the same instant.
> You can then read the buffer byte at your leisure. So no new
> instruction is necessary.

The 18 family PICs have exactly this feature.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@102617 by Olin Lathrop

face picon face
> for an example of better method A, how's this;
> * get LO, store it (critical timer read)
> * get HI (2 cycles since we got LO)
> * if LO is FE or FF; dec HI
> which is possibly the best method. :o)

As long as the prescaler is 1:1.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@103827 by Roman Black

flavicon
face
Olin Lathrop wrote:
>
> > for an example of better method A, how's this;
> > * get LO, store it (critical timer read)
> > * get HI (2 cycles since we got LO)
> > * if LO is FE or FF; dec HI
> > which is possibly the best method. :o)
>
> As long as the prescaler is 1:1.


Obviously. My point is that this method will always
read an exact 16bit timer read with no latency.
The "dissatisfying" Microchip example in the
datasheet (that someone originally referred to
and I was commenting on) has a major problem that
most reads will be immediate while some reads will
be significantly delayed, which sounds to me like a
useless way to read a timer.
-Roman

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@112617 by Dave Tweed

face
flavicon
face
Wouter van Ooijen <KILLspamwouterKILLspamspamVOTI.NL> wrote:
> > I think I have a 10-instruction solution.
>
> That was too optimistic, I think 15 might be more like it. Still
> struggling. No other takers?

I came up with a 12-instruction solution, but didn't post because it wasn't
less than 10. The key is to have two comparison loops. I'm assuming that
interrupts won't lock you out long enough to miss an exact match on the
high byte of the timer.

       ; wait for an exact match on the high byte
loop1:
       movf tmr1h, w
       xorwf t1h, w
       btfss status, z
       goto loop1

       ; wait for low byte of timer >= low byte of trigger value (unsigned
       ; comparison), or for high byte to increment, which catches cases
       ; like when the trigger value is xxFF and the low byte of the timer
       ; appears to skip from FE to 00 because of an interrupt.
loop2:
       movf tmr1l, w
       subwf t1l, w
       btfsc status, c
       goto done

       movf tmr1h, w
       xorwf t1h, w
       btfsc status, z
       goto loop2
done:

-- Dave Tweed

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@113608 by Wouter van Ooijen

face picon face
A taker!

> I'm assuming that interrupts won't lock you out
> long enough to miss an exact match on the
> high byte of the timer.

That is a weak point
- the moment we are waiting for might have passed already when the code
is entered (I guess I did not specify that clearly)
- with 1:1 prescaler only 256 plus some instructions need to be spent in
an interrupt to cause a complete miss of the exact match

But dinner is in the oven now, so when the kids keep on playing I'll
study your solution and fetch my pen and paper for mine.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@115311 by Dave Tweed

face
flavicon
face
Wouter van Ooijen <RemoveMEwouterTakeThisOuTspamVOTI.NL> wrote:
> That is a weak point
> - the moment we are waiting for might have passed already when the code
> is entered (I guess I did not specify that clearly)

No, you clearly said that (T1H, T1L) represent a *future* value of
(TMR1H, TMR1L). I had to take you at your word. ;-)

> - with 1:1 prescaler only 256 plus some instructions need to be spent in
> an interrupt to cause a complete miss of the exact match

If you've got ISRs of 256+ instructions, then there's not much point in
looking at the low byte of the timer at all. Since you specified 16-bit
timer values and a 1:1 prescaler, I figured it was safe to assume that
ISRs were fairly short.

Ignoring the low byte simplifies things quite a bit. Now, how much
"negative future" do we need to allow for?

-- Dave Tweed

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@125602 by Scott Dattalo

face
flavicon
face
On Thu, 27 Feb 2003, Wouter van Ooijen wrote:

> coding challenge:
>
> - 14-bit core PIC
> - forget about paging and banking issues
> - smallest possible code
> - assembler
>
> TMR1 is a free-running 16-bit timer that can be read as two file
> registers TMR1H and TMR1L. Note that there is no buffering in the
> reading, so for 00FF you might read FF as low byte and then 01 as high
> byte (just after the rollover).

How about this for reading the clock:

   movf   TMR1L,W       ; grab TMR1
   movwf  TMR1L_buff
   movf   TMR1H,W
   movwf  TMR1H_buff

 ; Check for rollover. If the low byte increments from ff to 00 then
 ; there's a rollover and we need to advance the high byte by one count
 ; However, the low byte may be any value between 0xfd and 0xff at
 ; the point we read it above. If it was then, well we have a rollover.
 ; One way to capture this condition is by monitoring the upper bit
 ; of TMR1L. If it is high when we read it above, and low when we read
 ; it next (just below), then a rollover has occurred. In fact, we
 ; have about 255 cycles to capture this rollover condition -
 ; anywhere from the first read being 0x80 to 0xff and the second
 ; read being 00 to 0x7f.  If interrupts are enabled, then we need
 ; to ensure no isr takes longer than 255 cycles.
 ;
   comf   TMR1L,W       ;
   andlw  0x80
   skpz
    incf  TMR1H_buff,F



{Quote hidden}

Now check to see if you're close to the target value.

  if( abs(target - current) < threshold)
    you're close.

If threshold is 255, then this untested code might do the trick:

   movf   T1L,W
   subwf  TMR1L_Buff,F
   movf   T1H,W
   skpc
    incfsz T1H,W
     subwf TMR1H_buff,F

   skpnz
    goto   close

   skpc
    incfsz TMR1H_buff,W
     goto  not_close


This can be optimized....

Scott

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

2003\02\27@130446 by Scott Dattalo

face
flavicon
face
On Thu, 27 Feb 2003, Scott Dattalo wrote:

> On Thu, 27 Feb 2003, Wouter van Ooijen wrote:
>
> > coding challenge:
> >
> > - 14-bit core PIC
> > - forget about paging and banking issues
> > - smallest possible code
> > - assembler
> >
> > TMR1 is a free-running 16-bit timer that can be read as two file
> > registers TMR1H and TMR1L. Note that there is no buffering in the
> > reading, so for 00FF you might read FF as low byte and then 01 as high
> > byte (just after the rollover).
>
> How about this for reading the clock:

Actually, I forgot an instruction

{Quote hidden}

     andwf  TMR1L_buff

>     andlw  0x80
>     skpz
>      incf  TMR1H_buff,F

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


'[PIC]: coding challenge: await'
2003\03\01@205554 by Scott Dattalo
face
flavicon
face
On Thu, 27 Feb 2003, Scott Dattalo wrote:

<snip>

{Quote hidden}

I'm surprised no one noticed a really glaring error in the code that I
posted. The low byte of the saved TMR was not adjusted if a rollover was
detected. Here (I think) is a correction:

    movf   TMR1L,W       ; grab TMR1
    movwf  temp
    incf   TMR1H,W       ;Assume that the low byte is about to rollover
    movwf  TMR1H_buff

  ; Check for rollover. If the low byte increments from ff to 00 then
  ; there's a rollover and we need to advance the high byte by one count
  ; However, the low byte may be any value between 0xfd and 0xff at
  ; the point we read it above. If it was then, well we have a rollover.
  ; One way to capture this condition is by monitoring the upper bit
  ; of TMR1L. If it is high when we read it above, and low when we read
  ; it next (just below), then a rollover has occurred. In fact, we
  ; have about 255 cycles to capture this rollover condition -
  ; anywhere from the first read being 0x80 to 0xff and the second
  ; read being 00 to 0x7f.  If interrupts are enabled, then we need
  ; to ensure no isr takes longer than 255 cycles.

    movf   TMR1L,W       ; Read the low value again
    movwf  TMR1L_buff    ; and save it

    btfsc  temp,7        ;If TMR1L on the first read was < 0x80
     btfsc TMR1L_buff,7  ;or if the both reads are between
      decf TMR1H_buff,F  ;0x80 and 0xff then leave the high byte alone

The last three instructions will decrement the TMR1H value if the first
read of TMR1L was less than 0x80 or if the two reads of TMR1L are both
between 0x80 and 0xff. Note that the decrement just cancels the increment
from above. The only condition that the decrement will not be executed is
if the first read of TMR1L is between 0x80 and 0xff *and* the second read
of TMR1L is between 0 and 0x7f - in other words, if TMR1L has rolled over.

Here's a solution that saves one instruction:

    rlf    TMR1L,W       ; read the msb of tmr1L --> Carry
    incf   TMR1H,W       ;Assume that the low byte is about to rollover
    movwf  TMR1H_buff

    movf   TMR1L,W
    movwf  TMR1L_buff

    skpnc                ;If TMR1L on the first read was < 0x80
     btfsc TMR1L_buff,7  ;or if the both reads are between
      decf TMR1H_buff,F  ;0x80 and 0xff then leave the high byte alone

8 instructions. Any more optimizations?

Scott

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spamBeGonelistservspamBeGonespammitvma.mit.edu with SET PICList DIGEST in the body

2003\03\02@161352 by o-8859-1?Q?Tony_K=FCbek?=

flavicon
face
Hi,
I haven't read most if this thread so at the moment I have no
code to post, however I saw this bit from Scott Dattalo:
<snip>
>Here's a solution that saves one instruction:
>
>    rlf    TMR1L,W       ; read the msb of tmr1L --> Carry
>     incf   TMR1H,W       ;Assume that the low byte is about to
rollover
>     movwf  TMR1H_buff
>
>     movf   TMR1L,W
>     movwf  TMR1L_buff
>
>     skpnc                ;If TMR1L on the first read was < 0x80
>      btfsc TMR1L_buff,7  ;or if the both reads are between
>       decf TMR1H_buff,F  ;0x80 and 0xff then leave the high byte alone

Wouldn't the "incf TMR1H,W " possibly trash the carry ? (if TMR1H is
0xFF)


/Tony

--
http://www.piclist.com hint: To leave the PICList
TakeThisOuTpiclist-unsubscribe-requestEraseMEspamspam_OUTmitvma.mit.edu>

2003\03\02@163047 by Banjo Spam

picon face
Tony,

My copy of PIC16F87xA manual (DS39582A, page 158)
indicates that C (and DC for that matter) are not
affected by the INCF instruction. Note that because
INCF only increments by one, Z can be tested as if it
were the carry bit, for the INCF.

Only ADD and SUB commands (ADDWF, SUBWF, ADDLW, SUBLW)
affect C/DC. Note also that these commands do not USE
the value of C/DC for the arithmetic calculation. This
requires using bit-test functions when adding
multiple-byte values, as in the numerous math routines
available on piclist.com. On the other hand, it does
not require clearing/setting the C/DC values prior to
these functions.

I would expect that other PICMicro processors are the
similar, but I would check the Instruction Set Summary
to be sure.

Happy pic'n!

--- Tony_K|bek <RemoveMEtony.kubekspamTakeThisOuTFLINTAB.COM> wrote:
{Quote hidden}

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspammitvma.mit.edu>

2003\03\02@163505 by Scott Dattalo

face
flavicon
face
On Sun, 2 Mar 2003, Tony K|bek wrote:

{Quote hidden}

On the 18F452, yes. But this is for the midrange PIC's. And if you recall,
INCF does not affect the carry on the 12 and 14 bit cores like it does on
the 16-bit cores.

BTW, there still is a bug in the code above.

also, BTW, I re-read Dave Tweed's solution. His solution is the best for
solving the problem that was asked.

Scott

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestEraseMEspamEraseMEmitvma.mit.edu>

2003\03\16@165019 by Dmitriy A. Kiryashov

picon face
Hi Scott.

It looks very optimal to me. Pre-inc followed by correction.


WBR Dmitry.

PS Sorry for being some sort of slow guy... ;)
I'm reading Piclist twice a month currently.


{Quote hidden}

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservspam_OUTspamKILLspammitvma.mit.edu with SET PICList DIGEST in the body

2003\03\16@191828 by Scott Dattalo

face
flavicon
face
On Sun, 16 Mar 2003, Dmitriy A. Kiryashov wrote:

{Quote hidden}

But it has a bug...

Consider this case:
                         ;TMR1
    rlf    TMR1L,W       ;00FF  -- W = 0xFC or 0xFD, Carry = 1
    incf   TMR1H,W       ;0100  -- W = 02
    movwf  TMR1H_buff    ;0101  -- TMR1H_buff = 02

    movf   TMR1L,W       ;0102  -- W = 02
    movwf  TMR1L_buff    ;0103  -- TMR1L_buff = 02

    skpnc                ;0104  -- skip is not taken
     btfsc TMR1L_buff,7  ;0105  -- This skip is taken
      decf TMR1H_buff,F  ;0106  -- this instruction is skipped

Final value: TMR1_buff = 0202  :(

Probably the best thing to do is something like this:

    movf   TMR1H,W
    movwf  TMR1H_buff
    decf   TMR1L,W
    movwf  TMR1L_buff
    decf   TMR1L_buff,w

or

    movf   TMR1H,W
    movwf  TMR1H_buff
    movlw  -2
    addwf  TMR1L,W
    movwf  TMR1L_buff

But this has the drawback that it can't tolerate an interrupt.

Scott

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservTakeThisOuTspamspammitvma.mit.edu with SET PICList DIGEST in the body

More... (looser matching)
- Last day of these posts
- In 2003 , 2004 only
- Today
- New search...