Searching \ for '[PIC]: Multibyte words and Interrupts' 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/ints.htm?key=interrupt
Search entire site for: 'Multibyte words and Interrupts'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Multibyte words and Interrupts'
2000\11\06@104320 by Michael Rigby-Jones

flavicon
face
If I have a main loop that uses a lot of 16 and 32 bit variables which need
to be accessed (but not changed) in the ISR for sending the values accross
an I2C bus. Is there a good way to ensure a whole word has been loaded
before an Interrupt is serviced?  i.e. if a 16 bit word is being updated in
the main loop, this will obviously take at least 2 operations, probably more
like 4.  If an interrupt occurrs in the middle of this, the word will
neither contain the new value or the old value, but a bit of each, which is
obvioiusly undesirable.  Switching off interrupts for every multibyte
operation dosen't seem very practical.  I'm thinking that maybe I should
double buffer the variables I'm interested in, and only use the buffered
copies in the ISR...

e.g.

int a,b,c,d;
int buff_a,buff_b,buff_c,buff_d;

void main()
{

       while(1)
       {
               /* lots of 16/32 bit operations in main loop */
               a = (b*c)+d;    /* etc....etc....*/

               /* end of loop */
               while(GIE) GIE = 0;     /* disable interrupts */
               buff_a = a;             /* copy variables to buffers */
               buff_b = b;
               buff_c = c;
               buff_d = d;
               GIE = 1;                /* enable interrupts */
       }
}

So, what I would like to know is if there a better way of doing things that
dosen't use so much RAM?

Cheers

Mike

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use spam_OUTlistservTakeThisOuTspammitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@111038 by Andrew Kunz

flavicon
face
Yes, and it's rather simple.


DI ();         // entering critical section
<update values>
EI ();         // ISR can use them now.

Andy










Michael Rigby-Jones <.....mrjonesKILLspamspam@spam@NORTELNETWORKS.COM> on 11/06/2000 09:46:54 AM

Please respond to pic microcontroller discussion list <PICLISTspamKILLspamMITVMA.MIT.EDU>








To:      .....PICLISTKILLspamspam.....MITVMA.MIT.EDU

cc:      (bcc: Andrew Kunz/TDI_NOTES)



Subject: [PIC]: Multibyte words and Interrupts








If I have a main loop that uses a lot of 16 and 32 bit variables which need
to be accessed (but not changed) in the ISR for sending the values accross
an I2C bus. Is there a good way to ensure a whole word has been loaded
before an Interrupt is serviced?  i.e. if a 16 bit word is being updated in
the main loop, this will obviously take at least 2 operations, probably more
like 4.  If an interrupt occurrs in the middle of this, the word will
neither contain the new value or the old value, but a bit of each, which is
obvioiusly undesirable.  Switching off interrupts for every multibyte
operation dosen't seem very practical.  I'm thinking that maybe I should
double buffer the variables I'm interested in, and only use the buffered
copies in the ISR...

e.g.

int a,b,c,d;
int buff_a,buff_b,buff_c,buff_d;

void main()
{

       while(1)
       {
               /* lots of 16/32 bit operations in main loop */
               a = (b*c)+d;    /* etc....etc....*/

               /* end of loop */
               while(GIE) GIE = 0;     /* disable interrupts */
               buff_a = a;             /* copy variables to buffers */
               buff_b = b;
               buff_c = c;
               buff_d = d;
               GIE = 1;                /* enable interrupts */
       }
}

So, what I would like to know is if there a better way of doing things that
dosen't use so much RAM?

Cheers

Mike

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use EraseMElistservspam_OUTspamTakeThisOuTmitvma.mit.edu?body=SET%20PICList%20DIGEST

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use listservspamspam_OUTmitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@114702 by Andy Jancura

picon face
Or you can do something like this:

main()
{
 // before manipulating buffers

 while(Var_Locked == 1);

 Set_Buffer();
 Var_Locked = 1;
 Start_I2C();
}

ISR()
{
 if(Not_Send)
   // do your transfer

 else
   // last byte sended
   Var_Locked = 0;
}

Andrej

_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.

Share information about yourself, create your own public profile at
http://profiles.msn.com.

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use @spam@listservKILLspamspammitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@121205 by Eisermann, Phil [Ridg/CO]

flavicon
face
perhaps use a bit flag to indicate that you are done updating the variable?

-----Original Message-----
From: Michael Rigby-Jones [KILLspammrjonesKILLspamspamNORTELNETWORKS.COM]
Sent: Monday, November 06, 2000 9:47 AM
To: RemoveMEPICLISTTakeThisOuTspamMITVMA.MIT.EDU
Subject: [PIC]: Multibyte words and Interrupts


If I have a main loop that uses a lot of 16 and 32 bit variables which need
to be accessed (but not changed) in the ISR for sending the values accross
an I2C bus. Is there a good way to ensure a whole word has been loaded
before an Interrupt is serviced?  i.e. if a 16 bit word is being updated in
the main loop, this will obviously take at least 2 operations, probably more
like 4.  If an interrupt occurrs in the middle of this, the word will
neither contain the new value or the old value, but a bit of each, which is
obvioiusly undesirable.  Switching off interrupts for every multibyte
operation dosen't seem very practical.  I'm thinking that maybe I should
double buffer the variables I'm interested in, and only use the buffered
copies in the ISR...

e.g.

int a,b,c,d;
int buff_a,buff_b,buff_c,buff_d;

void main()
{

       while(1)
       {
               /* lots of 16/32 bit operations in main loop */
               a = (b*c)+d;    /* etc....etc....*/

               /* end of loop */
               while(GIE) GIE = 0;     /* disable interrupts */
               buff_a = a;             /* copy variables to buffers */
               buff_b = b;
               buff_c = c;
               buff_d = d;
               GIE = 1;                /* enable interrupts */
       }
}

So, what I would like to know is if there a better way of doing things that
dosen't use so much RAM?

Cheers

Mike

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use spamBeGonelistservspamBeGonespammitvma.mit.edu?body=SET%20PICList%20DIGEST

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use TakeThisOuTlistservEraseMEspamspam_OUTmitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@125549 by Olin Lathrop

flavicon
face
> DI ();         // entering critical section
> <update values>
> EI ();         // ISR can use them now.

This is not so nice when <update values> takes a long time.  In this
particular case, it means getting bytes from an IIC bus, so double buffering
is a much better idea.


*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, RemoveMEolinspamTakeThisOuTcognivis.com, http://www.cognivis.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use listservEraseMEspam.....mitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@125553 by Olin Lathrop
flavicon
face
> I'm thinking that maybe I should
> double buffer the variables I'm interested in, and only use the buffered
> copies in the ISR...

That was my reaction too.  You can then afford to disable interrupts when
the value is copied from one buffer to the other.


*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, EraseMEolinspamcognivis.com, http://www.cognivis.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use RemoveMElistservEraseMEspamEraseMEmitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@134554 by Mike Mansheim

flavicon
face
depends...
I like a flag that tells the isr whether or not the data is valid;
however, this means that some instances of the interrupt will
not send any data (the isr just returns if the data valid flag
isn't set).
If the variables are double-buffered, then the isr will always send
data, but it may be the old data.
I wonder why an isr to i2c the data out??  Why not just put the ic2
xmit at the end of the variable manipulations in the main while(1)
loop?  If that makes the the xmits happen too often, maintain a
counter and only xmit every nth time thru the loop.  If that isn't
precise enough, use the isr to maintain a clock and set a flag
when it is time to transmit.
I'm assuming the interrupt is internally timer generated - if it
is in response to an external request, then the double-buffered
example you gave could miss the request while the interrupts are
disabled.

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use RemoveMElistservspam_OUTspamKILLspammitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@154038 by M. Adam Davis

flavicon
face
Why don't you do some intelligent double buffering:

Two locations for the data (16 bit or more)
One pointer to the known good location.

Your interrupt simply puts the pointer into the FSR, and uses the data at
that location.

Your update code puts the new data into the unused buffer, and when it is
done you update one variable - the pointer.

There is no need to disable the interrupt or anything.

The only other thing to do is to have a flag which is set/cleared by the
interrupt, or your code, but not both (interrupt: I'm in the middle of a
transmission, don't change the registers, or code: I'm updating the
registers, don't transmit)

-Adam

Michael Rigby-Jones wrote:
{Quote hidden}

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use EraseMElistservspamspamspamBeGonemitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@161803 by Bob Ammerman

picon face
----- Original Message -----
From: M. Adam Davis <RemoveMEadavisKILLspamspamUBASICS.COM>
To: <PICLISTSTOPspamspamspam_OUTMITVMA.MIT.EDU>
Sent: Monday, November 06, 2000 3:41 PM
Subject: Re: [PIC]: Multibyte words and Interrupts


> Why don't you do some intelligent double buffering:
>
> Two locations for the data (16 bit or more)
> One pointer to the known good location.

This is a very good idea. It even handles the case where task and interrupt
level can both set the value. But you will find you need three locations for
the data in the general case where the value can be written at interrupt or
task level:

For example:

 CBLOCK    xxx
   shared_val_int:2 ; interrupt written copy of  value
   shared_val_a:2   ; one task written copy of value
   shared_val_b:2   ; another task written copy of value
   shared_val_ptr    ; pointer to most recently written value
ENDC

Interrupt and task level both access (read) by saying:

   movf     shared_val_ptr,W
   movwf  FSR

   movf     INDF,W
   ..do something..
   incf       FSR,F
   movf     INDF,W
   ..do something..

Interrupt level writes the value:

   movlw    xxx
   movwf    shared_val_int
   movlw    yyy
   movwf    shared_val_int+1
   movlw    shared_val_int
   movwf    shared_val_ptr

Task level writes the value:

   movwf    shared_val_ptr
   xorlw      shared_val_a                ; Is the pointer equal to A?
   skpnz
   xorlw      shared_val_b^shared_val_b    ; Yes: prepare to write B
   xorlw      shared_val_a                ; Fix it
   movwf    FSR

   movlw    xxx
   movwf    INDF
   incf         FSR,F
   movlw    yyy
   movwf    INDF

   movf      FSR,W
   movwf   shared_val_ptr

Here is a question:

Why does task level require two copies of the shared value (shared_val_a and
shared_val_b), but interrupt level gets away with a single copy?

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use spamBeGonelistservSTOPspamspamEraseMEmitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\07@031626 by Michael Rigby-Jones

flavicon
face
> -----Original Message-----
> From: Mike Mansheim [SMTP:KILLspamMichael_J_MansheimspamBeGonespamGRACO.COM]
> Sent: Monday, November 06, 2000 6:22 PM
> To:   EraseMEPICLISTspamEraseMEMITVMA.MIT.EDU
> Subject:      Re: [PIC]: Multibyte words and Interrupts
>
> depends...
> I like a flag that tells the isr whether or not the data is valid;
> however, this means that some instances of the interrupt will
> not send any data (the isr just returns if the data valid flag
> isn't set).
> If the variables are double-buffered, then the isr will always send
> data, but it may be the old data.
> I wonder why an isr to i2c the data out??  Why not just put the ic2
> xmit at the end of the variable manipulations in the main while(1)
> loop?
>
The reason for this is that I am using the MSSP in Slave mode, which really
does need to be interrupt driven to  give the fastest response to the
master.

>  If that makes the the xmits happen too often, maintain a
> counter and only xmit every nth time thru the loop.  If that isn't
> precise enough, use the isr to maintain a clock and set a flag
> when it is time to transmit.
> I'm assuming the interrupt is internally timer generated - if it
> is in response to an external request, then the double-buffered
> example you gave could miss the request while the interrupts are
> disabled.
>
Probably didn''t explain the whole thing too well, but the PIC will
essentialy be for real time monitoring of 32 analogue inputs via
multiplexors and 16 or more digital inputs.  It will also have to control 8
digital outputs depending on either the state of the analogue inputs or on a
request from the I2C master.  The master can request the value of any of the
analogue or digital channels.

Now my first idea was to perform all the monitoring and control in the main
loop, and use the interrupt purely for comms.  There is no fixed requirement
for the loop time, this isn't a closed loop control system so the monitoring
does not have to work to an exact period.

Thinking about this a bit further, I guess I could do monitoring under a
timer interrupt.  If I checked the state of the SSPIF flag after every
critical section I could ensure a reasonable latency for the comms, and
there should be no way the I2C should be able to retreive a half written
word.  The main loop would effectively be empty, just a watchdog reset I
guess.

Alternatively, I could move the I2C out of interrupt control and just poll
it in the main loop, but perform monitoring under a timer interrupt.  This
would mean worst case latency would be the entire monitor rouine...unless I
split it up into smaller chunks.

Any comments?  I'm most impressed with the response to this so far!

Mike

--
http://www.piclist.com hint: To leave the PICList
@spam@piclist-unsubscribe-request@spam@spamspam_OUTmitvma.mit.edu




2000\11\07@040729 by Michael Rigby-Jones

flavicon
face
> -----Original Message-----
> From: Andrew Kunz [SMTP:spamBeGoneakunzspamKILLspamTDIPOWER.COM]
> Sent: Monday, November 06, 2000 4:12 PM
> To:   .....PICLISTspam_OUTspamMITVMA.MIT.EDU
> Subject:      Re: [PIC]: Multibyte words and Interrupts
>
> Yes, and it's rather simple.
>
>
> DI ();         // entering critical section
> <update values>
> EI ();         // ISR can use them now.
>
> Andy
>
>
>
The trouble is, because the main loop is pretty much only updating these
variables, the interrupts would be disabled most of the time!

       Mike

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




2000\11\07@042646 by Andy Jancura

picon face
{Quote hidden}

Hi Mike,

I would say start with time analysis of every task. From this you get all
necessary information. Then put the slowest task to main and the fastest to
ISR. To comunicate between the two tasks, you would need only from main to
isr with bit flags and double buffered results from isr. You can spare all
your copying very easy, total 4-6 instruktions.

Andrej

_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.

Share information about yourself, create your own public profile at
http://profiles.msn.com.

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




2000\11\07@065316 by Bob Ammerman

picon face
----- Original Message -----
From: Michael Rigby-Jones <.....mrjonesspamRemoveMENORTELNETWORKS.COM>
To: <RemoveMEPICLISTspamspamBeGoneMITVMA.MIT.EDU>
Sent: Tuesday, November 07, 2000 4:05 AM
Subject: Re: [PIC]: Multibyte words and Interrupts


> > {Original Message removed}

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