Project

General

Profile

Statistics
| Branch: | Revision:

robobuggy / arduino / InterruptRCRecieverReference / PinChangeInt / RELEASE_NOTES @ c5d6b0e8

History | View | Annotate | Download (19.2 KB)

1
******************************************************************************
2

    
3
	PinChangeInt
4
	---- RELEASE NOTES --- 
5

    
6
Version 2.19 (beta) Tue Nov 20 07:33:37 CST 2012
7
SANGUINO SUPPORT!  ...And Mioduino! 
8
...The ATmega644 chip is so cool, how can I not? 4 full ports of Pin Change Interrupt bliss! 32 i/o pins! 64k Flash! 4k RAM! Well I wish I had one. That said, Sanguino users, PLEASE send in your bug or bliss reports! Your interrupt-loving brethren and sistren are depending on you, so I can assure everyone that my changes work on that platform. Thanks.
9

    
10
Modified the addPin() method to save 12 bytes; thanks again robtilllart!
11
    if (firstPin != NULL) {
12
        tmp=firstPin;
13
        do {
14
            if (tmp->arduinoPin == arduinoPin) { enable(tmp, userFunc, mode); return(0); }
15
            if (tmp->next == NULL) break;
16
            tmp=tmp->next;
17
        } while (true);
18
    }
19
Also changed the goto in the PCint() loop to be a while/break combination. No change to
20
code speed, but it looks better and passes the cleanliness "gut check".
21

    
22
Includes PinChangeIntTest 1.5 sketch.
23

    
24
...Ooops!  Forgot the GetPSTR library, needed for the PinChangeIntTest code!  Now it's included.
25
******************************************************************************
26
Version 2.17 (beta) Sat Nov 17 09:46:50 CST 2012
27
Another bugfix in the PCINT_MULTI_SERVICE section.  I was using sbi(PCIFR, PCICRbit); 
28
I didn't realize that was for I/O ports, and not ATmega registers.
29
But according to "deprecated.h", 
30
"These macros became obsolete, as reading and writing IO ports can
31
 be done by simply using the IO port name in an expression, and all
32
 bit manipulation (including those on IO ports) can be done using
33
 generic C bit manipulation operators."
34
So now I do:
35
      PCIFR |= PCICRbit;
36
******************************************************************************
37
Version 2.15 (beta) Sat Nov 17 01:17:44 CST 2012
38
Fixed it so that attachInterrupt() will now follow your changes to the user function,
39
as well as the mode. detachInterrupt() still does not delete the PCintPin object but
40
at least you can detach and reattach at will, using different modes (RISING, FALLING,
41
CHANGE) and different functions as you wish.
42

    
43
******************************************************************************
44
Version 2.13 (beta) Mon Nov 12 09:33:06 CST 2012
45
SIGNIFICANT BUGFIX release! Significant changes:
46
1. PCintPort::curr bug. Interrupts that occur rapidly will likely not get serviced properly by PCint().
47
2. PCint() interrupt handler optimization.
48
3. PCIFR port bit set bug fix.
49
4. Many static variables added for debugging; used only when #define PINMODE is on.
50
5. detachInterrupt() no longer does a delete(), since that wasn't working anyway. When you detachInterrupt(), the PORT just disables interrupts for that pin; the PCintPin object remains in memory and in the linked list of pins (possibly slowing down your interrupts a couple of micros).  You can reenable a detached interrupt- but you must do it within the PinChangeInt library (would anyone ever enable an interrupt on a pin, then disable it, then have need to reenable it but not using the library?).
51
6. attachInterrupt() now returns a uint8_t value:  1 on successful attach, 0 on successful attach but using an already-enabled pin, and -1 if the new() operator failed to create a PCintPin object.
52
Also, modified these release notes.
53

    
54
Details:
55

    
56
Uncovered a nasty bug, thanks to robtillaart on the Arduino Forums and Andre' Franken who posted to the PinChangeInt groups. This bug was introduced by me when I assigned PCintPort::curr early in the interrupt handler:
57
ISR(PCINT0_vect) {
58
    PCintPort::curr = portB.portInputReg;
59
    portB.PCint();
60
}
61
Later, in the interrupt handler PCint(), we loop as long as PCIFR indicates a new interrupt wants to be triggered, provided DISABLE_PCINT_MULTI_SERVICE is not defined (it is not by default):
62
#ifndef DISABLE_PCINT_MULTI_SERVICE
63
	pcifr = PCIFR & PCICRbit;
64
	PCIFR = pcifr;  // clear the interrupt if we will process it (no effect if bit is zero)
65
} while(pcifr);
66
#endif
67
...Well. Problem is, if a pin pops up and causes the PCIFR to change, we have to reread the port and look at how it is now! I wasn't doing that before, so if a new interrupt appeared while I was still servicing the old one, odd behavior would take place. For example, an interrupt would register but then the userFunc would not be called upon to service it.  The code needs to be:
68
	pcifr = PCIFR & PCICRbit;
69
	PCIFR = pcifr;  // clear the interrupt if we will process it (no effect if bit is zero)
70
    	PCintPort::curr=portInputReg; // ...Fixed in 2.11beta.
71
} while(pcifr);
72

    
73
Also, made the interrupt handler even faster with an optimization from robtillaart to take out the checks for changed pins from the while() loop that steps through the pins:
74
uint8_t changedPins = (PCintPort::curr ^ lastPinView) &
75
                      ((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr ));
76

    
77
...This speedup is offset by more changes in the PCint() handler, which now looks like the following; there are two bug fixes:
78
----------------------------
79
FIX 1: sbi(PCIFR, PCICRbit);
80
FIX 2: ...the aforementioned PCintPort::curr=portInputReg;
81
Here's the new code:
82
----------------------------
83
    #ifndef DISABLE_PCINT_MULTI_SERVICE
84
        pcifr = PCIFR & PCICRbit;
85
        if (pcifr) {
86
        //if (PCIFR & PCICRbit) { // believe it or not, this adds .6 micros
87
            sbi(PCIFR, PCICRbit); // This was a BUG: PCIFR = pcifr  ...And here is the fix.
88
            #ifdef PINMODE
89
            PCintPort::pcint_multi++;
90
            if (PCIFR & PCICRbit) PCintPort::PCIFRbug=1; // PCIFR & PCICRbit should ALWAYS be 0 here!
91
            #endif
92
            PCintPort::curr=portInputReg; // ...Fixed in 2.11beta.
93
            goto loop;  // A goto!!! Don't want to look at the portInputReg gratuitously, so the while() will not do.
94
        }
95
    #endif
96

    
97
Also I added a lot of variables for debugging when PINMODE is defined, for routing out nasty bugs. I may need them in the future... :-(
98

    
99
Finally, I am not putting newlines in this commentary so I can make it easier to paste online.
100

    
101
******************************************************************************
102
Version 2.11 (beta) Mon Nov 12 09:33:06 CST 2012
103
See version 2.13 (beta) above. No change other than tidying up the release notes.
104
******************************************************************************
105
	Version 2.01 (beta) Thu Jun 28 12:35:48 CDT 2012
106
	...Wow, Version 2!  What?  Why?
107
	Modified the way that the pin is tested inside the interrupt subroutine (ISR) PCintPort::PCint(),
108
	to make the interrupt quicker and slightly reduce the memory footprint.  The interrupt's time is
109
	reduced by 2 microseconds or about 7%.  Instead of using the mode variable, two bitmasks are maintained
110
	for each port.  One bitmask contains all the pins that are configured to work on RISING signals, the other
111
	on FALLING signals.  A pin configured to work on CHANGE signals will appear in both bitmasks of the port.
112
   	Then, the test for a change goes like this:
113
		if (thisChangedPin) {
114
     		if ((thisChangedPin & portRisingPins & PCintPort::curr ) ||
115
         		(thisChangedPin & portFallingPins & ~PCintPort::curr )) {
116
	where portRisingPins is the bitmask for the pins configured to interrupt on RISING signals, and
117
	portFallingPins is the bitmask for the pins configured to interrupt on FALLING signals.  Each port includes
118
	these two bitmask variables.
119

    
120
	This is a significant change to some core functionality to the library, and it saves an appreciable amount
121
	of time (2 out of 36 or so micros).  Hence, the 2.00 designation.
122

    
123
	Tue Jun 26 12:42:20 CDT 2012
124
	I was officially given permission to use the PCint library:
125

    
126
	Re: PCint library
127
	« Sent to: GreyGnome on: Today at 08:10:33 AM »
128
	« You have forwarded or responded to this message. »
129
	Quote  Reply  Remove  
130
	HI,
131
  	Yeah, I wrote the original PCint library. It was a bit of a hack and the new one has better features. 
132
	I intended the code to be freely usable.  Didn't really think about a license.  Feel free to use it in
133
	your code: I hereby grant you permission.
134
	
135
  	I'll investigate the MIT license, and see if it is appropriate.
136
	Chris J. Kiick
137
	Robot builder and all around geek.
138

    
139
	Version 1.81 (beta) Tue Jun 19 07:29:08 CDT 2012
140
	Created the getPCIntVersion function, and its associated GET_PCINT_VERSION preprocessor macro.  The version
141
	is a 16-bit int, therefore versions are represented as a 4-digit integer.  1810, then, is the first beta
142
	release of 1.81x series.  1811 would be a bugfix of 1.810. 1820 would be the production release.
143

    
144
	Reversed the order of this list, so the most recent notes come first.
145

    
146
	Made some variables "volatile", because they are changed in the interrupt code.  Thanks, Tony Cappellini!
147

    
148
	Added support for the Arduino Mega!  Thanks to cserveny...@gmail.com!
149
	NOTE:  I don't have a Mega, so I rely on you to give me error (or working) reports!
150
	To sum it up for the Mega:  No Port C, no Port D.  Instead, you get Port J and Port K.  Port B remains.
151
	Port J, however, is practically useless because there is only 1 pin available for interrupts.
152
	Most of the Port J pins are not even connected to a header connector.  Caveat Programmer.
153

    
154
	Created a function to report the version of this code.  Put this #define ahead of the #include of this file,
155
	in your sketch:
156
		#define GET_PCINT_VERSION
157
	Then you can call
158
		uint16_t getPCIntVersion ();
159
	and it will return a 16-bit integer representation of the version of this library.  That is, version 1.73beta
160
	will be reported as "1730".  1.74, then, will return "1740". And so on, for whatever version of the library
161
	this happens to be.  The odd number in the 10's position will indicate a beta version, as per usual, and the
162
	number in the 1s place will indicate the beta revision (bugs may necessitate a 1.731, 1.732, etc.).
163

    
164
   	Here are some of his notes based on his changes:
165
	Mega and friends are using port B, J and K for interrupts.  B is working without any modifications.
166

    
167
	J is mostly useless, because of the hardware UART. I was not able to get pin change notifications from
168
	the TX pin (14), so only 15 left. All other (PORT J) pins are not connected on the Arduino boards.
169

    
170
	K controls Arduino pin A8-A15, working fine.
171

    
172
	328/168 boards use C and D.  So in case the lib is compiled with Mega target, the C and D will be
173
	disabled.  Also you cannot see port J/K with other targets.  For J and K new flags introduced:
174
	NO_PORTJ_PINCHANGES and NO_PORTK_PINCHANGES.
175
	Maybe we should have PORTJ_PINCHANGES to enable PJ, because they will be most likely unused.
176

    
177
	Enjoy!
178

    
179
	Note:  To remain consistent, I have not included PORTJ_PINCHANGES.  All ports behave the same,
180
	no matter how trivial those ports may seem... no surprises...
181

    
182
	Version 1.72 Wed Mar 14 18:57:55 CDT 2012
183
	Release.
184

    
185
	Version 1.71beta Sat Mar 10 12:57:05 CST 2012
186
	Code reordering: Starting in version 1.3 of this library, I put the code that enables
187
	interrupts for the given pin, and the code that enables Pin Change Interrupts, ahead of actually
188
	setting the user's function for the pin.  Thus in the small interval between turning on the
189
	interrupts and actually creating a valid link to an interrupt handler, it is possible to get an
190
	interrupt.  At that point the value of the pointer is 0, so this means that the Arduino
191
	will start over again from memory location 0- just as if you'd pressed the reset button.  Oops!
192

    
193
	I corrected it so the code now operates in the proper order.
194
	(EDITORIAL NOTE:  If you want to really learn something, teach it!)
195

    
196
	Minor code clean-up:  All references to PCintPort::curr are now explicit.  This changes the compiled
197
	hex code not one whit.  I just sleep better at night.
198

    
199
	Numbering:  Changed the numbering scheme.  Beta versions will end with an odd number in the hundredths
200
	place- because they may be odd- and continue to be marked "beta".  I'll just sleep better at night. :-)
201

    
202
	Version 1.70beta Mon Feb 27 07:20:42 CST 2012
203
	Happy Birthday to me!  Happy Birthday tooooo meee!  Happy Birthday, Dear Meeeeee-eeeee!
204
	Happy Birthday to me!
205

    
206
	Yes, it is on this auspicious occasion of mine (and Elizabeth Taylor's [R.I.P.]) birthday that I
207
	humbly submit to you, gracious Arduino PinChangeInt user, version 1.70beta of the PinChangeInt
208
	library.  I hope you enjoy it.
209

    
210
	New in this release:
211
    The PinChangeIntTest sketch was created, which can be found in the Examples directory.  It exercises:
212
	* Two interrupting pins, one on each of the Arduino's PORTs.
213
	* detachInterrupt() (and subsequent attachInterrupt()s).
214
	Hopefully this will help avoid the embarrassing bugs that I have heretofore missed.
215

    
216
	As well, it has come to this author's (GreyGnome) attention that the Serial class in Arduino 1.0
217
	uses an interrupt that, if you attempt to print from an interrupt (which is what I was doing in my
218
	tests) can easily lock up the Arduino.  So I have taken SigurðurOrn's excellent ByteBuffer library
219
	and modified it for my own nefarious purposes.  (see http://siggiorn.com/?p=460).  The zipfile
220
        comes complete with the ByteBuffer library; see the ByteBuffer/ByteBuffer.h file for a list of
221
	changes, and see the PinChangeIntTest sketch for a usage scenario.  Now the (interrupt-less and)
222
	relatively fast operation of filling a circular buffer is used in the interrupt routines.  The buffer
223
	is then printed from loop().
224

    
225
	The library has been modified so it can be used in other libraries, such as my AdaEncoder library
226
	(http://code.google.com/p/adaencoder/).  When #include'd by another library you should #define
227
	the LIBCALL_PINCHANGEINT macro.  For example:
228
	#ifndef PinChangeInt_h
229
	#define LIBCALL_PINCHANGEINT
230
	#include "../PinChangeInt/PinChangeInt.h"
231
	#endif
232
	This is necessary because the IDE compiles both your sketch and the .cpp file of your library, and
233
	the .h file is included in both places.  But since the .h file actually contains the code, any variable
234
	or function definitions would occur twice and cause compilation errors- unless #ifdef'ed out.
235

    
236
	Version 1.6beta Fri Feb 10 08:48:35 CST 2012
237
	Set the value of the current register settings, first thing in each ISR; e.g.,
238
	ISR(PCINT0_vect) {
239
		PCintPort::curr = portB.portInputReg; // version 1.6
240
		...
241
	...instead of at the beginning of the PCintPort::PCint() static method.  This means that the port is read
242
	closer to the beginning of the interrupt, and may be slightly more accurate- only by a couple of microseconds,
243
	really, but it's a cheap win.
244

    
245
	Fixed a bug- a BUG!- in the attachInterrupt() and detachInterrupt() methods.  I didn't have breaks in my
246
	switch statements!  Augh!  What am I, a (UNIX) shell programmer?  ...Uh, generally, yes...
247

    
248
	Added the PINMODE define and the PCintPort::pinmode variable.
249

    
250
	Version 1.51 Sun Feb  5 23:28:02 CST 2012
251
	Crap, a bug!  Changed line 392 from this:
252
	PCintPort::pinState=curr & changedPins ? HIGH : LOW;
253
	to this:
254
	PCintPort::pinState=curr & p->mask ? HIGH : LOW;
255
	Also added a few lines of (commented-out) debug code.
256

    
257
	Version 1.5 Thu Feb  2 18:09:49 CST 2012
258
	Added the PCintPort::pinState static variable to allow the programmer to query the state of the pin
259
	at the time of interrupt.
260
	Added two new #defines, NO_PIN_STATE and NO_PIN_NUMBER so as to reduce the code size by 20-50 bytes,
261
	and to speed up the interrupt routine slightly by declaring that you don't care if the static variables
262
	PCintPort::pinState and/or PCintPort::arduinoPin are set and made available to your interrupt routine.
263
	// #define NO_PIN_STATE        // to indicate that you don't need the pinState
264
	// #define NO_PIN_NUMBER       // to indicate that you don't need the arduinoPin
265

    
266
	Version 1.4 Tue Jan 10 09:41:14 CST 2012
267
	All the code has been moved into this .h file, so as to allow #define's to work from the user's
268
	sketch.  Thanks to Paul Stoffregen from pjrc.com for the inspiration! (Check out his website for
269
	some nice [lots more memory] Arduino-like boards at really good prices.  ...This has been an unsolicited
270
	plug. Now back to our regular programming.  ...Hehe, "programming", get it?)
271

    
272
	As a result, we no longer use the PinChangeIntConfig.h file.  The user must #define things in his/her
273
	sketch.  Which is better anyway.
274

    
275
	Removed the pcIntPorts[] array, which created all the ports by default no matter what.  Now, only
276
	those ports (PCintPort objects) that you need will get created if you use the NO_PORTx_PINCHANGES #defines.
277
   	This saves flash memory, and actually we get a bit of a memory savings anyway even if all the ports are
278
	left enabled.
279

    
280
	The attachInterrupt and detachInterrupt routines were modified to handle the new PCintPort objects.
281

    
282
	Version 1.3 Sat Dec  3 22:56:20 CST 2011
283
	Significant internal changes:
284
	Tested and modified to work with Arduino 1.0.
285

    
286
	Modified to use the new() operator and symbolic links instead of creating a pre-populated
287
	PCintPins[].  Renamed some variables to simplify or make their meaning more obvious (IMHO anyway).
288
	Modified the PCintPort::PCint() code (ie, the interrupt code) to loop over a linked-list.  For
289
	those who love arrays, I have left some code in there that should work to loop over an array
290
	instead.  But it is commented out in the release version.
291

    
292
	For Arduino versions prior to 1.0: The new() operator requires the cppfix.h library, which is
293
	included with this package.  For Arduino 1.0 and above: new.h comes with the distribution, and
294
	that is #included.
295

    
296
	Version 1.2 Sat Dec  3 Sat Dec  3 09:15:52 CST 2011
297
	Modified Thu Sep  8 07:33:17 CDT 2011 by GreyGnome.  Fixes a bug with the initial port
298
	value.  Now it sets the initial value to be the state of the port at the time of
299
	attachInterrupt().  The line is port.PCintLast=port.portInputReg; in attachInterrupt().
300
	See GreyGnome comment, below.
301

    
302
	Added the "arduinoPin" variable, so the user's function will know exactly which pin on
303
	the Arduino was triggered.
304

    
305
	Version 1.1 Sat Dec  3 00:06:03 CST 2011
306
	...updated to fix the "delPin" function as per "pekka"'s bug report.  Thanks!
307

    
308
	---- ^^^ VERSIONS ^^^ (NOTE TO SELF: Update the PCINT_VERSION define, below) -------------
309

    
310
	See google code project for latest, bugs and info http://code.google.com/p/arduino-pinchangeint/
311
	For more information Refer to avr-gcc header files, arduino source and atmega datasheet.
312

    
313
	This library was inspired by and derived from "johnboiles" (it seems) 
314
	PCInt Arduino Playground example here: http://www.arduino.cc/playground/Main/PcInt
315
	If you are the original author, please let us know at the google code page
316
	
317
	It provides an extension to the interrupt support for arduino by
318
	adding pin change interrupts, giving a way for users to have
319
	interrupts drive off of any pin.
320

    
321
	This program is free software: you can redistribute it and/or modify
322
	it under the terms of the GNU General Public License as published by
323
	the Free Software Foundation, either version 3 of the License, or
324
	(at your option) any later version.
325

    
326
	This program is distributed in the hope that it will be useful,
327
	but WITHOUT ANY WARRANTY; without even the implied warranty of
328
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
329
	GNU General Public License for more details.
330

    
331
	You should have received a copy of the GNU General Public License
332
	along with this program.  If not, see <http://www.gnu.org/licenses/>.