diff --git a/extras/Doxyfile b/extras/Doxyfile
index 402bd94..0c2dadb 100644
--- a/extras/Doxyfile
+++ b/extras/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = "Task scheduler library"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.0
+PROJECT_NUMBER = 1.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/extras/html/_r_e_a_d_m_e_8md_source.html b/extras/html/_r_e_a_d_m_e_8md_source.html
index c57ae18..28d72e1 100644
--- a/extras/html/_r_e_a_d_m_e_8md_source.html
+++ b/extras/html/_r_e_a_d_m_e_8md_source.html
@@ -3,8 +3,7 @@
4 This library implements a simple, preemptive task scheduler that is executed in parallel to the 1ms timer interrupt
5 used for the Arduino millis() function. It allows to define cyclic tasks or tasks that should be executed in the future
6 in parallel to the normal program execution inside the main loop.
7
8 The task scheduler is executed every 1ms. A possibly running task is interrupted by this and only resumed after all succeeding tasks have finished. This means
9 that always the task started last has the highest priority. This effect needs to be kept in mind when programming a software using this library.
10
11 Notes:
12 - Deadlocks can appear when one task waits for another taks which was started before.
13 - Timing critical tasks may not execute properly when they are interrupted for too long by other tasks. Thus it is recommended to keep task execution as short as possible.
14 - The Arduino MEGA leaves the interrupts state shortly after starting the task scheduler which makes the scheduler reentrant and allows any other interrupt (timer, UART, etc.) to be triggered.
15 - The Arduino DUE enables other interrupts by using the lowest possible priority (15) for the task scheduler interrupt.
16
17 Warning: The Arduino Due does not support reeantrant interrupts due to HW limitations. This means that unlike the Arduino MEGA the DUE is not able to execute
18 fast 1ms tasks several times before finishing a slower tasks with for example a 10ms timebase. This problem will be especially visible if the sum of the
19 execution time of all tasks is greater than the execution period of the fastest task.
20
21 Supported Boards:
22 - all boards using the Atmel ATMega328 controller, e.g. Arduino Uno and Nano
23 - all boards using the Atmel ATMega2560 controller, e.g. Arduino Mega
24 - all boards using the Atmel SAM3X8E controller, e.g. Arduino Due
25
26 Consumed interrupt:
27 - Atmel ATMega328 & ATMega2560: Scheduler uses TIMER0_COMPA interrupt. This maintains millis() and analogWrite() functionality on T0 pins. However,
28 frequent changes of the duty cycle using analogWrite() lead to a jitter in scheduler timing.
29 - Atmel SAM3X8E: Scheduler uses TC3 interrupt.
30
31 CPU runtime:
32 - Atmel ATMega328 & ATMega2560:
33 - 5μs without pending tasks
34 - 12μs + task duration when tasks are executed
35 - Atmel SAM3X8E:
36 - tbdμs without pending tasks
37 - tbdμs + task duration when tasks are executed
38
39 Have fun!
40
41 ====================================
42
43 # Revision History
44
45 1.0 (2019-10-12):
46 - initial release
+
1 Arduino Task Scheduler
+
2 ----------------------
+
3
+
4 This library implements a simple, preemptive task scheduler that is executed in parallel to the 1ms timer interrupt
+
5 used for the Arduino millis() function. It allows to define cyclic tasks or tasks that should be executed in the future
+
6 in parallel to the normal program execution inside the main loop.
+
7
+
8 The task scheduler is executed every 1ms. A possibly running task is interrupted by this and only resumed after all succeeding tasks have finished. This means
+
9 that always the task started last has the highest priority. This effect needs to be kept in mind when programming a software using this library.
+
10
+
11 Notes:
+
12 - Deadlocks can appear when one task waits for another taks which was started before.
+
13 - Timing critical tasks may not execute properly when they are interrupted for too long by other tasks. Thus it is recommended to keep task execution as short as possible.
+
14 - The Arduino MEGA leaves the interrupts state shortly after starting the task scheduler which makes the scheduler reentrant and allows any other interrupt (timer, UART, etc.) to be triggered.
+
15 - The Arduino DUE enables other interrupts by using the lowest possible priority (15) for the task scheduler interrupt.
+
16
+
17 Warning: The Arduino Due does not support reeantrant interrupts due to HW limitations. This means that unlike the Arduino MEGA the DUE is not able to execute
+
18 fast 1ms tasks several times before finishing a slower tasks with for example a 10ms timebase. This problem will be especially visible if the sum of the
+
19 execution time of all tasks is greater than the execution period of the fastest task.
+
20
+
21 Supported Boards:
+
22 - all boards using the Atmel ATMega328 controller, e.g. Arduino Uno and Nano
+
23 - all boards using the Atmel ATMega2560 controller, e.g. Arduino Mega
+
24 - all boards using the Atmel SAM3X8E controller, e.g. Arduino Due
+
25
+
26 Consumed interrupt:
+
27 - Atmel ATMega328 & ATMega2560: Scheduler uses TIMER0_COMPA interrupt. This maintains millis() and analogWrite() functionality on T0 pins. However,
+
28 frequent changes of the duty cycle using analogWrite() lead to a jitter in scheduler timing.
+
29 - Atmel SAM3X8E: Scheduler uses TC3 interrupt.
+
30
+
31 CPU runtime:
+
32 - Atmel ATMega328 & ATMega2560:
+
33 - 5μs without pending tasks
+
34 - 12μs + task duration when tasks are executed
+
35 - Atmel SAM3X8E:
+
36 - tbdμs without pending tasks
+
37 - tbdμs + task duration when tasks are executed
55bool SchedulingActive; // false = Scheduling stopped, true = Scheduling active (no configuration allowed)
56 int16_t _timebase; // 1ms counter (on ATMega 1.024ms, is compensated)
57 int16_t _nexttime; // time of next task call
58 uint8_t _lasttask; // last task in the tasks array (cauting! This variable starts is not counting from 0 to x but from 1 to x meaning that a single tasks will be at SchedulingTable[0] but _lasttask will have the value '1')
59
60
61#if defined(__SAM3X8E__)
62/*
63 Code from https://forum.arduino.cc/index.php?topic=130423.0
54bool SchedulingActive; // false = Scheduling stopped, true = Scheduling active (no configuration allowed)
+
55 int16_t _timebase; // 1ms counter (on ATMega 1.024ms, is compensated)
+
56 int16_t _nexttime; // time of next task call
+
57 uint8_t _lasttask; // last task in the tasks array (cauting! This variable starts is not counting from 0 to x but from 1 to x meaning that a single tasks will be at SchedulingTable[0] but _lasttask will have the value '1')
+
58
+
59
+
60#if defined(__SAM3X8E__)
+
61/*
+
62 Code from https://forum.arduino.cc/index.php?topic=130423.0
Example prototype for a function than can be executed as a task.
@@ -152,14 +174,12 @@
Deadlocks can appear when one task waits for another taks which was started before. Additionally it is likely that timing critical tasks will not execute properly when they are interrupted for too long by other tasks. Thus it is recommended to keep the tasks as small and fast as possible.
The Arduino ATMega (8-bit AVR) leaves the interrupts state shortly after starting the task scheduler which makes the scheduler reentrant and allows any other interrupt (timer, UART, etc.) to be triggered. The Arduino SAM (32-bit ARM) enables other interrupts by using the lowest possible priority (15) for the task scheduler interrupt. Warning The Arduino SAM does not support reeantrant interrupts due to HW limitations. This means that unlike the Arduino ATMega the DUE is not able to execute fast 1ms tasks several times before finishing a slower tasks with for example a 10ms timebase. This problem will be especially visible if the sum of the execution time of all tasks is greater than the execution period of the fastest task.
This library implements a simple, preemptive task scheduler that is executed in parallel to the 1ms timer interrupt used for the Arduino millis() function. It allows to define cyclic tasks or tasks that should be executed in the future in parallel to the normal program execution inside the main loop.
diff --git a/extras/html/jquery.js b/extras/html/jquery.js
index f5343ed..1f4d0b4 100644
--- a/extras/html/jquery.js
+++ b/extras/html/jquery.js
@@ -65,23 +65,4 @@
Released under MIT license.
https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
*/
-(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(k){var A=k(document),s=k(window),w=k("body");var n="displayController",e="hasActiveHover",d="forcedOpen",u="hasMouseMove",f="mouseOnToPopup",g="originalTitle",y="powertip",o="powertipjq",l="powertiptarget",E=180/Math.PI;var c={isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var p={none:0,top:1,bottom:2,left:4,right:8};k.fn.powerTip=function(F,N){if(!this.length){return this}if(k.type(F)==="string"&&k.powerTip[F]){return k.powerTip[F].call(this,this,N)}var O=k.extend({},k.fn.powerTip.defaults,F),G=new x(O);h();this.each(function M(){var R=k(this),Q=R.data(y),P=R.data(o),T=R.data(l),S;if(R.data(n)){k.powerTip.destroy(R)}S=R.attr("title");if(!Q&&!T&&!P&&S){R.data(y,S);R.data(g,S);R.removeAttr("title")}R.data(n,new t(R,O,G))});if(!O.manual){this.on({"mouseenter.powertip":function J(P){k.powerTip.show(this,P)},"mouseleave.powertip":function L(){k.powerTip.hide(this)},"focus.powertip":function K(){k.powerTip.show(this)},"blur.powertip":function H(){k.powerTip.hide(this,true)},"keydown.powertip":function I(P){if(P.keyCode===27){k.powerTip.hide(this,true)}}})}return this};k.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false};k.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};k.powerTip={show:function z(F,G){if(G){i(G);c.previousX=G.pageX;c.previousY=G.pageY;k(F).data(n).show()}else{k(F).first().data(n).show(true,true)}return F},reposition:function r(F){k(F).first().data(n).resetPosition();return F},hide:function D(G,F){if(G){k(G).first().data(n).hide(F)}else{if(c.activeHover){c.activeHover.data(n).hide(true)}}return G},destroy:function C(G){k(G).off(".powertip").each(function F(){var I=k(this),H=[g,n,e,d];if(I.data(g)){I.attr("title",I.data(g));H.push(y)}I.removeData(H)});return G}};k.powerTip.showTip=k.powerTip.show;k.powerTip.closeTip=k.powerTip.hide;function b(){var F=this;F.top="auto";F.left="auto";F.right="auto";F.bottom="auto";F.set=function(H,G){if(k.isNumeric(G)){F[H]=Math.round(G)}}}function t(K,N,F){var J=null;function L(P,Q){M();if(!K.data(e)){if(!P){c.tipOpenImminent=true;J=setTimeout(function O(){J=null;I()},N.intentPollInterval)}else{if(Q){K.data(d,true)}F.showTip(K)}}}function G(P){M();c.tipOpenImminent=false;if(K.data(e)){K.data(d,false);if(!P){c.delayInProgress=true;J=setTimeout(function O(){J=null;F.hideTip(K);c.delayInProgress=false},N.closeDelay)}else{F.hideTip(K)}}}function I(){var Q=Math.abs(c.previousX-c.currentX),O=Math.abs(c.previousY-c.currentY),P=Q+O;if(P",{id:Q.popupId});if(w.length===0){w=k("body")}w.append(O)}if(Q.followMouse){if(!O.data(u)){A.on("mousemove",M);s.on("scroll",M);O.data(u,true)}}if(Q.mouseOnToPopup){O.on({mouseenter:function L(){if(O.data(f)){if(c.activeHover){c.activeHover.data(n).cancel()}}},mouseleave:function N(){if(c.activeHover){c.activeHover.data(n).hide()}}})}function I(S){S.data(e,true);O.queue(function R(T){H(S);T()})}function H(S){var U;if(!S.data(e)){return}if(c.isTipOpen){if(!c.isClosing){K(c.activeHover)}O.delay(100).queue(function R(V){H(S);V()});return}S.trigger("powerTipPreRender");U=B(S);if(U){O.empty().append(U)}else{return}S.trigger("powerTipRender");c.activeHover=S;c.isTipOpen=true;O.data(f,Q.mouseOnToPopup);if(!Q.followMouse){G(S);c.isFixedTipOpen=true}else{M()}O.fadeIn(Q.fadeInTime,function T(){if(!c.desyncTimeout){c.desyncTimeout=setInterval(J,500)}S.trigger("powerTipOpen")})}function K(R){c.isClosing=true;c.activeHover=null;c.isTipOpen=false;c.desyncTimeout=clearInterval(c.desyncTimeout);R.data(e,false);R.data(d,false);O.fadeOut(Q.fadeOutTime,function S(){var T=new b();c.isClosing=false;c.isFixedTipOpen=false;O.removeClass();T.set("top",c.currentY+Q.offset);T.set("left",c.currentX+Q.offset);O.css(T);R.trigger("powerTipClose")})}function M(){if(!c.isFixedTipOpen&&(c.isTipOpen||(c.tipOpenImminent&&O.data(u)))){var R=O.outerWidth(),V=O.outerHeight(),U=new b(),S,T;U.set("top",c.currentY+Q.offset);U.set("left",c.currentX+Q.offset);S=m(U,R,V);if(S!==p.none){T=a(S);if(T===1){if(S===p.right){U.set("left",c.windowWidth-R)}else{if(S===p.bottom){U.set("top",c.scrollTop+c.windowHeight-V)}}}else{U.set("left",c.currentX-R-Q.offset);U.set("top",c.currentY-V-Q.offset)}}O.css(U)}}function G(S){var R,T;if(Q.smartPlacement){R=k.fn.powerTip.smartPlacementLists[Q.placement];k.each(R,function(U,W){var V=m(F(S,W),O.outerWidth(),O.outerHeight());T=W;if(V===p.none){return false}})}else{F(S,Q.placement);T=Q.placement}O.addClass(T)}function F(U,T){var R=0,S,W,V=new b();V.set("top",0);V.set("left",0);O.css(V);do{S=O.outerWidth();W=O.outerHeight();V=P.compute(U,T,S,W,Q.offset);O.css(V)}while(++R<=5&&(S!==O.outerWidth()||W!==O.outerHeight()));return V}function J(){var R=false;if(c.isTipOpen&&!c.isClosing&&!c.delayInProgress){if(c.activeHover.data(e)===false||c.activeHover.is(":disabled")){R=true}else{if(!v(c.activeHover)&&!c.activeHover.is(":focus")&&!c.activeHover.data(d)){if(O.data(f)){if(!v(O)){R=true}}else{R=true}}}if(R){K(c.activeHover)}}}this.showTip=I;this.hideTip=K;this.resetPosition=G}function q(F){return window.SVGElement&&F[0] instanceof SVGElement}function h(){if(!c.mouseTrackingActive){c.mouseTrackingActive=true;k(function H(){c.scrollLeft=s.scrollLeft();c.scrollTop=s.scrollTop();c.windowWidth=s.width();c.windowHeight=s.height()});A.on("mousemove",i);s.on({resize:function G(){c.windowWidth=s.width();c.windowHeight=s.height()},scroll:function F(){var I=s.scrollLeft(),J=s.scrollTop();if(I!==c.scrollLeft){c.currentX+=I-c.scrollLeft;c.scrollLeft=I}if(J!==c.scrollTop){c.currentY+=J-c.scrollTop;c.scrollTop=J}}})}}function i(F){c.currentX=F.pageX;c.currentY=F.pageY}function v(F){var H=F.offset(),J=F[0].getBoundingClientRect(),I=J.right-J.left,G=J.bottom-J.top;return c.currentX>=H.left&&c.currentX<=H.left+I&&c.currentY>=H.top&&c.currentY<=H.top+G}function B(I){var G=I.data(y),F=I.data(o),K=I.data(l),H,J;if(G){if(k.isFunction(G)){G=G.call(I[0])}J=G}else{if(F){if(k.isFunction(F)){F=F.call(I[0])}if(F.length>0){J=F.clone(true,true)}}else{if(K){H=k("#"+K);if(H.length>0){J=H.html()}}}}return J}function m(M,L,K){var G=c.scrollTop,J=c.scrollLeft,I=G+c.windowHeight,F=J+c.windowWidth,H=p.none;if(M.topI||Math.abs(M.bottom-c.windowHeight)>I){H|=p.bottom}if(M.leftF){H|=p.left}if(M.left+L>F||M.right1){return}h.preventDefault();var j=h.originalEvent.changedTouches[0],g=document.createEvent("MouseEvents");g.initMouseEvent(i,true,true,window,1,j.screenX,j.screenY,j.clientX,j.clientY,false,false,false,false,0,null);h.target.dispatchEvent(g)}d._touchStart=function(h){var g=this;if(a||!g._mouseCapture(h.originalEvent.changedTouches[0])){return}a=true;g._touchMoved=false;e(h,"mouseover");e(h,"mousemove");e(h,"mousedown")};d._touchMove=function(g){if(!a){return}this._touchMoved=true;e(g,"mousemove")};d._touchEnd=function(g){if(!a){return}e(g,"mouseup");e(g,"mouseout");if(!this._touchMoved){e(g,"click")}a=false};d._mouseInit=function(){var g=this;g.element.bind({touchstart:b.proxy(g,"_touchStart"),touchmove:b.proxy(g,"_touchMove"),touchend:b.proxy(g,"_touchEnd")});f.call(g)};d._mouseDestroy=function(){var g=this;g.element.unbind({touchstart:b.proxy(g,"_touchStart"),touchmove:b.proxy(g,"_touchMove"),touchend:b.proxy(g,"_touchEnd")});c.call(g)}})(jQuery);/*!
- * SmartMenus jQuery Plugin - v1.0.0 - January 27, 2016
- * http://www.smartmenus.org/
- *
- * Copyright Vasil Dinkov, Vadikom Web Ltd.
- * http://vadikom.com
- *
- * Licensed MIT
- */
-(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{if(typeof module==="object"&&typeof module.exports==="object"){module.exports=a(require("jquery"))}else{a(jQuery)}}}(function(a){var b=[],e=!!window.createPopup,f=false,d="ontouchstart" in window,h=false,g=window.requestAnimationFrame||function(l){return setTimeout(l,1000/60)},c=window.cancelAnimationFrame||function(l){clearTimeout(l)};function k(m){var n=".smartmenus_mouse";if(!h&&!m){var o=true,l=null;a(document).bind(i([["mousemove",function(s){var t={x:s.pageX,y:s.pageY,timeStamp:new Date().getTime()};if(l){var q=Math.abs(l.x-t.x),p=Math.abs(l.y-t.y);if((q>0||p>0)&&q<=2&&p<=2&&t.timeStamp-l.timeStamp<=300){f=true;if(o){var r=a(s.target).closest("a");if(r.is("a")){a.each(b,function(){if(a.contains(this.$root[0],r[0])){this.itemEnter({currentTarget:r[0]});return false}})}o=false}}}l=t}],[d?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut",function(p){if(j(p.originalEvent)){f=false}}]],n));h=true}else{if(h&&m){a(document).unbind(n);h=false}}}function j(l){return !/^(4|mouse)$/.test(l.pointerType)}function i(l,n){if(!n){n=""}var m={};a.each(l,function(o,p){m[p[0].split(" ").join(n+" ")+n]=p[1]});return m}a.SmartMenus=function(m,l){this.$root=a(m);this.opts=l;this.rootId="";this.accessIdPrefix="";this.$subArrow=null;this.activatedItems=[];this.visibleSubMenus=[];this.showTimeout=0;this.hideTimeout=0;this.scrollTimeout=0;this.clickActivated=false;this.focusActivated=false;this.zIndexInc=0;this.idInc=0;this.$firstLink=null;this.$firstSub=null;this.disabled=false;this.$disableOverlay=null;this.$touchScrollingSub=null;this.cssTransforms3d="perspective" in m.style||"webkitPerspective" in m.style;this.wasCollapsible=false;this.init()};a.extend(a.SmartMenus,{hideAll:function(){a.each(b,function(){this.menuHideAll()})},destroy:function(){while(b.length){b[0].destroy()}k(true)},prototype:{init:function(n){var l=this;if(!n){b.push(this);this.rootId=(new Date().getTime()+Math.random()+"").replace(/\D/g,"");this.accessIdPrefix="sm-"+this.rootId+"-";if(this.$root.hasClass("sm-rtl")){this.opts.rightToLeftSubMenus=true}var r=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).bind(i([["mouseover focusin",a.proxy(this.rootOver,this)],["mouseout focusout",a.proxy(this.rootOut,this)],["keydown",a.proxy(this.rootKeyDown,this)]],r)).delegate("a",i([["mouseenter",a.proxy(this.itemEnter,this)],["mouseleave",a.proxy(this.itemLeave,this)],["mousedown",a.proxy(this.itemDown,this)],["focus",a.proxy(this.itemFocus,this)],["blur",a.proxy(this.itemBlur,this)],["click",a.proxy(this.itemClick,this)]],r));r+=this.rootId;if(this.opts.hideOnClick){a(document).bind(i([["touchstart",a.proxy(this.docTouchStart,this)],["touchmove",a.proxy(this.docTouchMove,this)],["touchend",a.proxy(this.docTouchEnd,this)],["click",a.proxy(this.docClick,this)]],r))}a(window).bind(i([["resize orientationchange",a.proxy(this.winResize,this)]],r));if(this.opts.subIndicators){this.$subArrow=a("").addClass("sub-arrow");if(this.opts.subIndicatorsText){this.$subArrow.html(this.opts.subIndicatorsText)}}k()}this.$firstSub=this.$root.find("ul").each(function(){l.menuInit(a(this))}).eq(0);this.$firstLink=this.$root.find("a").eq(0);if(this.opts.markCurrentItem){var p=/(index|default)\.[^#\?\/]*/i,m=/#.*/,q=window.location.href.replace(p,""),o=q.replace(m,"");this.$root.find("a").each(function(){var s=this.href.replace(p,""),t=a(this);if(s==q||s==o){t.addClass("current");if(l.opts.markCurrentTree){t.parentsUntil("[data-smartmenus-id]","ul").each(function(){a(this).dataSM("parent-a").addClass("current")})}}})}this.wasCollapsible=this.isCollapsible()},destroy:function(m){if(!m){var n=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").unbind(n).undelegate(n);n+=this.rootId;a(document).unbind(n);a(window).unbind(n);if(this.opts.subIndicators){this.$subArrow=null}}this.menuHideAll();var l=this;this.$root.find("ul").each(function(){var o=a(this);if(o.dataSM("scroll-arrows")){o.dataSM("scroll-arrows").remove()}if(o.dataSM("shown-before")){if(l.opts.subMenusMinWidth||l.opts.subMenusMaxWidth){o.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap")}if(o.dataSM("scroll-arrows")){o.dataSM("scroll-arrows").remove()}o.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})}if((o.attr("id")||"").indexOf(l.accessIdPrefix)==0){o.removeAttr("id")}}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("ie-shim").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded");this.$root.find("a.has-submenu").each(function(){var o=a(this);if(o.attr("id").indexOf(l.accessIdPrefix)==0){o.removeAttr("id")}}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub");if(this.opts.subIndicators){this.$root.find("span.sub-arrow").remove()}if(this.opts.markCurrentItem){this.$root.find("a.current").removeClass("current")}if(!m){this.$root=null;this.$firstLink=null;this.$firstSub=null;if(this.$disableOverlay){this.$disableOverlay.remove();this.$disableOverlay=null}b.splice(a.inArray(this,b),1)}},disable:function(l){if(!this.disabled){this.menuHideAll();if(!l&&!this.opts.isPopup&&this.$root.is(":visible")){var m=this.$root.offset();this.$disableOverlay=a('').css({position:"absolute",top:m.top,left:m.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(true),opacity:0}).appendTo(document.body)}this.disabled=true}},docClick:function(l){if(this.$touchScrollingSub){this.$touchScrollingSub=null;return}if(this.visibleSubMenus.length&&!a.contains(this.$root[0],l.target)||a(l.target).is("a")){this.menuHideAll()}},docTouchEnd:function(m){if(!this.lastTouch){return}if(this.visibleSubMenus.length&&(this.lastTouch.x2===undefined||this.lastTouch.x1==this.lastTouch.x2)&&(this.lastTouch.y2===undefined||this.lastTouch.y1==this.lastTouch.y2)&&(!this.lastTouch.target||!a.contains(this.$root[0],this.lastTouch.target))){if(this.hideTimeout){clearTimeout(this.hideTimeout);this.hideTimeout=0}var l=this;this.hideTimeout=setTimeout(function(){l.menuHideAll()},350)}this.lastTouch=null},docTouchMove:function(m){if(!this.lastTouch){return}var l=m.originalEvent.touches[0];this.lastTouch.x2=l.pageX;this.lastTouch.y2=l.pageY},docTouchStart:function(m){var l=m.originalEvent.touches[0];this.lastTouch={x1:l.pageX,y1:l.pageY,target:l.target}},enable:function(){if(this.disabled){if(this.$disableOverlay){this.$disableOverlay.remove();this.$disableOverlay=null}this.disabled=false}},getClosestMenu:function(m){var l=a(m).closest("ul");while(l.dataSM("in-mega")){l=l.parent().closest("ul")}return l[0]||null},getHeight:function(l){return this.getOffset(l,true)},getOffset:function(n,l){var m;if(n.css("display")=="none"){m={position:n[0].style.position,visibility:n[0].style.visibility};n.css({position:"absolute",visibility:"hidden"}).show()}var o=n[0].getBoundingClientRect&&n[0].getBoundingClientRect(),p=o&&(l?o.height||o.bottom-o.top:o.width||o.right-o.left);if(!p&&p!==0){p=l?n[0].offsetHeight:n[0].offsetWidth}if(m){n.hide().css(m)}return p},getStartZIndex:function(l){var m=parseInt(this[l?"$root":"$firstSub"].css("z-index"));if(!l&&isNaN(m)){m=parseInt(this.$root.css("z-index"))}return !isNaN(m)?m:1},getTouchPoint:function(l){return l.touches&&l.touches[0]||l.changedTouches&&l.changedTouches[0]||l},getViewport:function(l){var m=l?"Height":"Width",o=document.documentElement["client"+m],n=window["inner"+m];if(n){o=Math.min(o,n)}return o},getViewportHeight:function(){return this.getViewport(true)},getViewportWidth:function(){return this.getViewport()},getWidth:function(l){return this.getOffset(l)},handleEvents:function(){return !this.disabled&&this.isCSSOn()},handleItemEvents:function(l){return this.handleEvents()&&!this.isLinkInMegaMenu(l)},isCollapsible:function(){return this.$firstSub.css("position")=="static"},isCSSOn:function(){return this.$firstLink.css("display")=="block"},isFixed:function(){var l=this.$root.css("position")=="fixed";if(!l){this.$root.parentsUntil("body").each(function(){if(a(this).css("position")=="fixed"){l=true;return false}})}return l},isLinkInMegaMenu:function(l){return a(this.getClosestMenu(l[0])).hasClass("mega-menu")},isTouchMode:function(){return !f||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(p,l){var n=p.closest("ul"),q=n.dataSM("level");if(q>1&&(!this.activatedItems[q-2]||this.activatedItems[q-2][0]!=n.dataSM("parent-a")[0])){var m=this;a(n.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(n).each(function(){m.itemActivate(a(this).dataSM("parent-a"))})}if(!this.isCollapsible()||l){this.menuHideSubMenus(!this.activatedItems[q-1]||this.activatedItems[q-1][0]!=p[0]?q-1:q)}this.activatedItems[q-1]=p;if(this.$root.triggerHandler("activate.smapi",p[0])===false){return}var o=p.dataSM("sub");if(o&&(this.isTouchMode()||(!this.opts.showOnClick||this.clickActivated))){this.menuShow(o)}},itemBlur:function(m){var l=a(m.currentTarget);if(!this.handleItemEvents(l)){return}this.$root.triggerHandler("blur.smapi",l[0])},itemClick:function(o){var n=a(o.currentTarget);if(!this.handleItemEvents(n)){return}if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==n.closest("ul")[0]){this.$touchScrollingSub=null;o.stopPropagation();return false}if(this.$root.triggerHandler("click.smapi",n[0])===false){return false}var p=a(o.target).is("span.sub-arrow"),m=n.dataSM("sub"),l=m?m.dataSM("level")==2:false;if(m&&!m.is(":visible")){if(this.opts.showOnClick&&l){this.clickActivated=true}this.itemActivate(n);if(m.is(":visible")){this.focusActivated=true;return false}}else{if(this.isCollapsible()&&p){this.itemActivate(n);this.menuHide(m);return false}}if(this.opts.showOnClick&&l||n.hasClass("disabled")||this.$root.triggerHandler("select.smapi",n[0])===false){return false}},itemDown:function(m){var l=a(m.currentTarget);if(!this.handleItemEvents(l)){return}l.dataSM("mousedown",true)},itemEnter:function(n){var m=a(n.currentTarget);if(!this.handleItemEvents(m)){return}if(!this.isTouchMode()){if(this.showTimeout){clearTimeout(this.showTimeout);this.showTimeout=0}var l=this;this.showTimeout=setTimeout(function(){l.itemActivate(m)},this.opts.showOnClick&&m.closest("ul").dataSM("level")==1?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",m[0])},itemFocus:function(m){var l=a(m.currentTarget);if(!this.handleItemEvents(l)){return}if(this.focusActivated&&(!this.isTouchMode()||!l.dataSM("mousedown"))&&(!this.activatedItems.length||this.activatedItems[this.activatedItems.length-1][0]!=l[0])){this.itemActivate(l,true)}this.$root.triggerHandler("focus.smapi",l[0])},itemLeave:function(m){var l=a(m.currentTarget);if(!this.handleItemEvents(l)){return}if(!this.isTouchMode()){l[0].blur();if(this.showTimeout){clearTimeout(this.showTimeout);this.showTimeout=0}}l.removeDataSM("mousedown");this.$root.triggerHandler("mouseleave.smapi",l[0])},menuHide:function(m){if(this.$root.triggerHandler("beforehide.smapi",m[0])===false){return}m.stop(true,true);if(m.css("display")!="none"){var l=function(){m.css("z-index","")};if(this.isCollapsible()){if(this.opts.collapsibleHideFunction){this.opts.collapsibleHideFunction.call(this,m,l)}else{m.hide(this.opts.collapsibleHideDuration,l)}}else{if(this.opts.hideFunction){this.opts.hideFunction.call(this,m,l)}else{m.hide(this.opts.hideDuration,l)}}if(m.dataSM("ie-shim")){m.dataSM("ie-shim").remove().css({"-webkit-transform":"",transform:""})}if(m.dataSM("scroll")){this.menuScrollStop(m);m.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).unbind(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()}m.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false");m.attr({"aria-expanded":"false","aria-hidden":"true"});var n=m.dataSM("level");this.activatedItems.splice(n-1,1);this.visibleSubMenus.splice(a.inArray(m,this.visibleSubMenus),1);this.$root.triggerHandler("hide.smapi",m[0])}},menuHideAll:function(){if(this.showTimeout){clearTimeout(this.showTimeout);this.showTimeout=0}var m=this.opts.isPopup?1:0;for(var l=this.visibleSubMenus.length-1;l>=m;l--){this.menuHide(this.visibleSubMenus[l])}if(this.opts.isPopup){this.$root.stop(true,true);if(this.$root.is(":visible")){if(this.opts.hideFunction){this.opts.hideFunction.call(this,this.$root)}else{this.$root.hide(this.opts.hideDuration)}if(this.$root.dataSM("ie-shim")){this.$root.dataSM("ie-shim").remove()}}}this.activatedItems=[];this.visibleSubMenus=[];this.clickActivated=false;this.focusActivated=false;this.zIndexInc=0;this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(n){for(var l=this.activatedItems.length-1;l>=n;l--){var m=this.activatedItems[l].dataSM("sub");if(m){this.menuHide(m)}}},menuIframeShim:function(l){if(e&&this.opts.overlapControlsInIE&&!l.dataSM("ie-shim")){l.dataSM("ie-shim",a("").attr({src:"javascript:0",tabindex:-9}).css({position:"absolute",top:"auto",left:"0",opacity:0,border:"0"}))}},menuInit:function(l){if(!l.dataSM("in-mega")){if(l.hasClass("mega-menu")){l.find("ul").dataSM("in-mega",true)}var q=2,m=l[0];while((m=m.parentNode.parentNode)!=this.$root[0]){q++}var n=l.prevAll("a").eq(-1);if(!n.length){n=l.prevAll().find("a").eq(-1)}n.addClass("has-submenu").dataSM("sub",l);l.dataSM("parent-a",n).dataSM("level",q).parent().dataSM("sub",l);var o=n.attr("id")||this.accessIdPrefix+(++this.idInc),p=l.attr("id")||this.accessIdPrefix+(++this.idInc);n.attr({id:o,"aria-haspopup":"true","aria-controls":p,"aria-expanded":"false"});l.attr({id:p,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"});if(this.opts.subIndicators){n[this.opts.subIndicatorsPos](this.$subArrow.clone())}}},menuPosition:function(K){var r=K.dataSM("parent-a"),D=r.closest("li"),E=D.parent(),l=K.dataSM("level"),t=this.getWidth(K),J=this.getHeight(K),u=r.offset(),o=u.left,m=u.top,q=this.getWidth(r),F=this.getHeight(r),H=a(window),v=H.scrollLeft(),s=H.scrollTop(),z=this.getViewportWidth(),L=this.getViewportHeight(),w=E.parent().is("[data-sm-horizontal-sub]")||l==2&&!E.hasClass("sm-vertical"),B=this.opts.rightToLeftSubMenus&&!D.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&D.is("[data-sm-reverse]"),p=l==2?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,n=l==2?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY,C,A;if(w){C=B?q-t-p:p;A=this.opts.bottomToTopSubMenus?-J-n:F+n}else{C=B?p-t:q-p;A=this.opts.bottomToTopSubMenus?F-n-J:n}if(this.opts.keepInViewport){var N=o+C,M=m+A;if(B&&Nv+z){C=w?v+z-t-N+C:p-t}}if(!w){if(Js+L){A+=s+L-J-M}else{if(J>=L||Ms+L+0.49||ML+0.49){var G=this;if(!K.dataSM("scroll-arrows")){K.dataSM("scroll-arrows",a([a('')[0],a('')[0]]).bind({mouseenter:function(){K.dataSM("scroll").up=a(this).hasClass("scroll-up");G.menuScroll(K)},mouseleave:function(x){G.menuScrollStop(K);G.menuScrollOut(K,x)},"mousewheel DOMMouseScroll":function(x){x.preventDefault()}}).insertAfter(K))}var I=".smartmenus_scroll";K.dataSM("scroll",{y:this.cssTransforms3d?0:A-F,step:1,itemH:F,subH:J,arrowDownH:this.getHeight(K.dataSM("scroll-arrows").eq(1))}).bind(i([["mouseover",function(x){G.menuScrollOver(K,x)}],["mouseout",function(x){G.menuScrollOut(K,x)}],["mousewheel DOMMouseScroll",function(x){G.menuScrollMousewheel(K,x)}]],I)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:C+(parseInt(K.css("border-left-width"))||0),width:t-(parseInt(K.css("border-left-width"))||0)-(parseInt(K.css("border-right-width"))||0),zIndex:K.css("z-index")}).eq(w&&this.opts.bottomToTopSubMenus?0:1).show();if(this.isFixed()){K.css({"touch-action":"none","-ms-touch-action":"none"}).bind(i([[d?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp",function(x){G.menuScrollTouch(K,x)}]],I))}}}K.css({top:"auto",left:"0",marginLeft:C,marginTop:A-F});this.menuIframeShim(K);if(K.dataSM("ie-shim")){K.dataSM("ie-shim").css({zIndex:K.css("z-index"),width:t,height:J,marginLeft:C,marginTop:A-F})}},menuScroll:function(r,m,n){var p=r.dataSM("scroll"),q=r.dataSM("scroll-arrows"),o=p.up?p.upEnd:p.downEnd,s;if(!m&&p.momentum){p.momentum*=0.92;s=p.momentum;if(s<0.5){this.menuScrollStop(r);return}}else{s=n||(m||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(p.step))}var l=r.dataSM("level");if(this.activatedItems[l-1]&&this.activatedItems[l-1].dataSM("sub")&&this.activatedItems[l-1].dataSM("sub").is(":visible")){this.menuHideSubMenus(l-1)}p.y=p.up&&o<=p.y||!p.up&&o>=p.y?p.y:(Math.abs(o-p.y)>s?p.y+(p.up?s:-s):o);r.add(r.dataSM("ie-shim")).css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+p.y+"px, 0)",transform:"translate3d(0, "+p.y+"px, 0)"}:{marginTop:p.y});if(f&&(p.up&&p.y>p.downEnd||!p.up&&p.y0;if(m.dataSM("scroll-arrows").eq(l?0:1).is(":visible")){m.dataSM("scroll").up=l;this.menuScroll(m,true)}}n.preventDefault()},menuScrollOut:function(l,m){if(f){if(!/^scroll-(up|down)/.test((m.relatedTarget||"").className)&&(l[0]!=m.relatedTarget&&!a.contains(l[0],m.relatedTarget)||this.getClosestMenu(m.relatedTarget)!=l[0])){l.dataSM("scroll-arrows").css("visibility","hidden")}}},menuScrollOver:function(n,o){if(f){if(!/^scroll-(up|down)/.test(o.target.className)&&this.getClosestMenu(o.target)==n[0]){this.menuScrollRefreshData(n);var m=n.dataSM("scroll"),l=a(window).scrollTop()-n.dataSM("parent-a").offset().top-m.itemH;n.dataSM("scroll-arrows").eq(0).css("margin-top",l).end().eq(1).css("margin-top",l+this.getViewportHeight()-m.arrowDownH).end().css("visibility","visible")}}},menuScrollRefreshData:function(n){var m=n.dataSM("scroll"),l=a(window).scrollTop()-n.dataSM("parent-a").offset().top-m.itemH;if(this.cssTransforms3d){l=-(parseFloat(n.css("margin-top"))-l)}a.extend(m,{upEnd:l,downEnd:l+this.getViewportHeight()-m.subH})},menuScrollStop:function(l){if(this.scrollTimeout){c(this.scrollTimeout);this.scrollTimeout=0;l.dataSM("scroll").step=1;return true}},menuScrollTouch:function(p,q){q=q.originalEvent;if(j(q)){var m=this.getTouchPoint(q);if(this.getClosestMenu(m.target)==p[0]){var o=p.dataSM("scroll");if(/(start|down)$/i.test(q.type)){if(this.menuScrollStop(p)){q.preventDefault();this.$touchScrollingSub=p}else{this.$touchScrollingSub=null}this.menuScrollRefreshData(p);a.extend(o,{touchStartY:m.pageY,touchStartTime:q.timeStamp})}else{if(/move$/i.test(q.type)){var n=o.touchY!==undefined?o.touchY:o.touchStartY;if(n!==undefined&&n!=m.pageY){this.$touchScrollingSub=p;var l=nthis.getWidth(n)){n.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}}}this.menuPosition(n);if(n.dataSM("ie-shim")){n.dataSM("ie-shim").insertBefore(n)}}var l=function(){n.css("overflow","")};if(this.isCollapsible()){if(this.opts.collapsibleShowFunction){this.opts.collapsibleShowFunction.call(this,n,l)}else{n.show(this.opts.collapsibleShowDuration,l)}}else{if(this.opts.showFunction){this.opts.showFunction.call(this,n,l)}else{n.show(this.opts.showDuration,l)}}m.attr("aria-expanded","true");n.attr({"aria-expanded":"true","aria-hidden":"false"});this.visibleSubMenus.push(n);this.$root.triggerHandler("show.smapi",n[0])}},popupHide:function(l){if(this.hideTimeout){clearTimeout(this.hideTimeout);this.hideTimeout=0}var m=this;this.hideTimeout=setTimeout(function(){m.menuHideAll()},l?1:this.opts.hideTimeout)},popupShow:function(o,n){if(!this.opts.isPopup){alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.');return}if(this.hideTimeout){clearTimeout(this.hideTimeout);this.hideTimeout=0}this.$root.dataSM("shown-before",true).stop(true,true);if(!this.$root.is(":visible")){this.$root.css({left:o,top:n});this.menuIframeShim(this.$root);if(this.$root.dataSM("ie-shim")){this.$root.dataSM("ie-shim").css({zIndex:this.$root.css("z-index"),width:this.getWidth(this.$root),height:this.getHeight(this.$root),left:o,top:n}).insertBefore(this.$root)}var m=this,l=function(){m.$root.css("overflow","")};if(this.opts.showFunction){this.opts.showFunction.call(this,this.$root,l)}else{this.$root.show(this.opts.showDuration,l)}this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(true);this.init(true)},rootKeyDown:function(o){if(!this.handleEvents()){return}switch(o.keyCode){case 27:var m=this.activatedItems[0];if(m){this.menuHideAll();m[0].focus();var n=m.dataSM("sub");if(n){this.menuHide(n)}}break;case 32:var l=a(o.target);if(l.is("a")&&this.handleItemEvents(l)){var n=l.dataSM("sub");if(n&&!n.is(":visible")){this.itemClick({currentTarget:o.target});o.preventDefault()}}break}},rootOut:function(m){if(!this.handleEvents()||this.isTouchMode()||m.target==this.$root[0]){return}if(this.hideTimeout){clearTimeout(this.hideTimeout);this.hideTimeout=0}if(!this.opts.showOnClick||!this.opts.hideOnClick){var l=this;this.hideTimeout=setTimeout(function(){l.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(l){if(!this.handleEvents()||this.isTouchMode()||l.target==this.$root[0]){return}if(this.hideTimeout){clearTimeout(this.hideTimeout);this.hideTimeout=0}},winResize:function(m){if(!this.handleEvents()){if(this.$disableOverlay){var n=this.$root.offset();this.$disableOverlay.css({top:n.top,left:n.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}return}if(!("onorientationchange" in window)||m.type=="orientationchange"){var l=this.isCollapsible();if(!(this.wasCollapsible&&l)){if(this.activatedItems.length){this.activatedItems[this.activatedItems.length-1][0].blur()}this.menuHideAll()}this.wasCollapsible=l}}}});a.fn.dataSM=function(l,m){if(m){return this.data(l+"_smartmenus",m)}return this.data(l+"_smartmenus")};a.fn.removeDataSM=function(l){return this.removeData(l+"_smartmenus")};a.fn.smartmenus=function(m){if(typeof m=="string"){var l=arguments,o=m;Array.prototype.shift.call(l);return this.each(function(){var p=a(this).data("smartmenus");if(p&&p[o]){p[o].apply(p,l)}})}var n=a.extend({},a.fn.smartmenus.defaults,m);return this.each(function(){new a.SmartMenus(this,n)})};a.fn.smartmenus.defaults={isPopup:false,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:true,subIndicatorsPos:"prepend",subIndicatorsText:"+",scrollStep:30,scrollAccelerate:true,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(m,l){m.fadeOut(200,l)},collapsibleShowDuration:0,collapsibleShowFunction:function(m,l){m.slideDown(200,l)},collapsibleHideDuration:0,collapsibleHideFunction:function(m,l){m.slideUp(200,l)},showOnClick:false,hideOnClick:true,noMouseOver:false,keepInViewport:true,keepHighlighted:true,markCurrentItem:false,markCurrentTree:true,rightToLeftSubMenus:false,bottomToTopSubMenus:false,overlapControlsInIE:true};return a}));
\ No newline at end of file
+(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(k){var A=k(document),s=k(window),w=k("body");var n="displayController",e="hasActiveHover",d="forcedOpen",u="hasMouseMove",f="mouseOnToPopup",g="originalTitle",y="powertip",o="powertipjq",l="powertiptarget",E=180/Math.PI;var c={isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var p={none:0,top:1,bottom:2,left:4,right:8};k.fn.powerTip=function(F,N){if(!this.length){return this}if(k.type(F)==="string"&&k.powerTip[F]){return k.powerTip[F].call(this,this,N)}var O=k.extend({},k.fn.powerTip.defaults,F),G=new x(O);h();this.each(function M(){var R=k(this),Q=R.data(y),P=R.data(o),T=R.data(l),S;if(R.data(n)){k.powerTip.destroy(R)}S=R.attr("title");if(!Q&&!T&&!P&&S){R.data(y,S);R.data(g,S);R.removeAttr("title")}R.data(n,new t(R,O,G))});if(!O.manual){this.on({"mouseenter.powertip":function J(P){k.powerTip.show(this,P)},"mouseleave.powertip":function L(){k.powerTip.hide(this)},"focus.powertip":function K(){k.powerTip.show(this)},"blur.powertip":function H(){k.powerTip.hide(this,true)},"keydown.powertip":function I(P){if(P.keyCode===27){k.powerTip.hide(this,true)}}})}return this};k.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false};k.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};k.powerTip={show:function z(F,G){if(G){i(G);c.previousX=G.pageX;c.previousY=G.pageY;k(F).data(n).show()}else{k(F).first().data(n).show(true,true)}return F},reposition:function r(F){k(F).first().data(n).resetPosition();return F},hide:function D(G,F){if(G){k(G).first().data(n).hide(F)}else{if(c.activeHover){c.activeHover.data(n).hide(true)}}return G},destroy:function C(G){k(G).off(".powertip").each(function F(){var I=k(this),H=[g,n,e,d];if(I.data(g)){I.attr("title",I.data(g));H.push(y)}I.removeData(H)});return G}};k.powerTip.showTip=k.powerTip.show;k.powerTip.closeTip=k.powerTip.hide;function b(){var F=this;F.top="auto";F.left="auto";F.right="auto";F.bottom="auto";F.set=function(H,G){if(k.isNumeric(G)){F[H]=Math.round(G)}}}function t(K,N,F){var J=null;function L(P,Q){M();if(!K.data(e)){if(!P){c.tipOpenImminent=true;J=setTimeout(function O(){J=null;I()},N.intentPollInterval)}else{if(Q){K.data(d,true)}F.showTip(K)}}}function G(P){M();c.tipOpenImminent=false;if(K.data(e)){K.data(d,false);if(!P){c.delayInProgress=true;J=setTimeout(function O(){J=null;F.hideTip(K);c.delayInProgress=false},N.closeDelay)}else{F.hideTip(K)}}}function I(){var Q=Math.abs(c.previousX-c.currentX),O=Math.abs(c.previousY-c.currentY),P=Q+O;if(P",{id:Q.popupId});if(w.length===0){w=k("body")}w.append(O)}if(Q.followMouse){if(!O.data(u)){A.on("mousemove",M);s.on("scroll",M);O.data(u,true)}}if(Q.mouseOnToPopup){O.on({mouseenter:function L(){if(O.data(f)){if(c.activeHover){c.activeHover.data(n).cancel()}}},mouseleave:function N(){if(c.activeHover){c.activeHover.data(n).hide()}}})}function I(S){S.data(e,true);O.queue(function R(T){H(S);T()})}function H(S){var U;if(!S.data(e)){return}if(c.isTipOpen){if(!c.isClosing){K(c.activeHover)}O.delay(100).queue(function R(V){H(S);V()});return}S.trigger("powerTipPreRender");U=B(S);if(U){O.empty().append(U)}else{return}S.trigger("powerTipRender");c.activeHover=S;c.isTipOpen=true;O.data(f,Q.mouseOnToPopup);if(!Q.followMouse){G(S);c.isFixedTipOpen=true}else{M()}O.fadeIn(Q.fadeInTime,function T(){if(!c.desyncTimeout){c.desyncTimeout=setInterval(J,500)}S.trigger("powerTipOpen")})}function K(R){c.isClosing=true;c.activeHover=null;c.isTipOpen=false;c.desyncTimeout=clearInterval(c.desyncTimeout);R.data(e,false);R.data(d,false);O.fadeOut(Q.fadeOutTime,function S(){var T=new b();c.isClosing=false;c.isFixedTipOpen=false;O.removeClass();T.set("top",c.currentY+Q.offset);T.set("left",c.currentX+Q.offset);O.css(T);R.trigger("powerTipClose")})}function M(){if(!c.isFixedTipOpen&&(c.isTipOpen||(c.tipOpenImminent&&O.data(u)))){var R=O.outerWidth(),V=O.outerHeight(),U=new b(),S,T;U.set("top",c.currentY+Q.offset);U.set("left",c.currentX+Q.offset);S=m(U,R,V);if(S!==p.none){T=a(S);if(T===1){if(S===p.right){U.set("left",c.windowWidth-R)}else{if(S===p.bottom){U.set("top",c.scrollTop+c.windowHeight-V)}}}else{U.set("left",c.currentX-R-Q.offset);U.set("top",c.currentY-V-Q.offset)}}O.css(U)}}function G(S){var R,T;if(Q.smartPlacement){R=k.fn.powerTip.smartPlacementLists[Q.placement];k.each(R,function(U,W){var V=m(F(S,W),O.outerWidth(),O.outerHeight());T=W;if(V===p.none){return false}})}else{F(S,Q.placement);T=Q.placement}O.addClass(T)}function F(U,T){var R=0,S,W,V=new b();V.set("top",0);V.set("left",0);O.css(V);do{S=O.outerWidth();W=O.outerHeight();V=P.compute(U,T,S,W,Q.offset);O.css(V)}while(++R<=5&&(S!==O.outerWidth()||W!==O.outerHeight()));return V}function J(){var R=false;if(c.isTipOpen&&!c.isClosing&&!c.delayInProgress){if(c.activeHover.data(e)===false||c.activeHover.is(":disabled")){R=true}else{if(!v(c.activeHover)&&!c.activeHover.is(":focus")&&!c.activeHover.data(d)){if(O.data(f)){if(!v(O)){R=true}}else{R=true}}}if(R){K(c.activeHover)}}}this.showTip=I;this.hideTip=K;this.resetPosition=G}function q(F){return window.SVGElement&&F[0] instanceof SVGElement}function h(){if(!c.mouseTrackingActive){c.mouseTrackingActive=true;k(function H(){c.scrollLeft=s.scrollLeft();c.scrollTop=s.scrollTop();c.windowWidth=s.width();c.windowHeight=s.height()});A.on("mousemove",i);s.on({resize:function G(){c.windowWidth=s.width();c.windowHeight=s.height()},scroll:function F(){var I=s.scrollLeft(),J=s.scrollTop();if(I!==c.scrollLeft){c.currentX+=I-c.scrollLeft;c.scrollLeft=I}if(J!==c.scrollTop){c.currentY+=J-c.scrollTop;c.scrollTop=J}}})}}function i(F){c.currentX=F.pageX;c.currentY=F.pageY}function v(F){var H=F.offset(),J=F[0].getBoundingClientRect(),I=J.right-J.left,G=J.bottom-J.top;return c.currentX>=H.left&&c.currentX<=H.left+I&&c.currentY>=H.top&&c.currentY<=H.top+G}function B(I){var G=I.data(y),F=I.data(o),K=I.data(l),H,J;if(G){if(k.isFunction(G)){G=G.call(I[0])}J=G}else{if(F){if(k.isFunction(F)){F=F.call(I[0])}if(F.length>0){J=F.clone(true,true)}}else{if(K){H=k("#"+K);if(H.length>0){J=H.html()}}}}return J}function m(M,L,K){var G=c.scrollTop,J=c.scrollLeft,I=G+c.windowHeight,F=J+c.windowWidth,H=p.none;if(M.topI||Math.abs(M.bottom-c.windowHeight)>I){H|=p.bottom}if(M.leftF){H|=p.left}if(M.left+L>F||M.right8)) {
+ } if (imm || ($.browser.msie && $.browser.version>8)) {
// somehow slideDown jumps to the start of tree for IE9 :-(
$(node.getChildrenUL()).show();
} else {
$(node.getChildrenUL()).slideDown("fast");
}
- node.plus_img.innerHTML = arrowDown;
+ if (node.isLast) {
+ node.plus_img.src = node.relpath+"arrowdown.png";
+ } else {
+ node.plus_img.src = node.relpath+"arrowdown.png";
+ }
node.expanded = true;
}
}
@@ -336,7 +341,7 @@ function showNode(o, node, index, hash)
getNode(o, node);
}
$(node.getChildrenUL()).css({'display':'block'});
- node.plus_img.innerHTML = arrowDown;
+ node.plus_img.src = node.relpath+"arrowdown.png";
node.expanded = true;
var n = node.children[o.breadcrumbs[index]];
if (index+1=desktop_vp) {
- if (!collapsed) {
- collapseExpand();
- }
- } else if (width>desktop_vp && collapsedWidth0) {
- restoreWidth(0);
- collapsed=true;
- }
- else {
- var width = readCookie('width');
- if (width>200 && width<$(window).width()) { restoreWidth(width); } else { restoreWidth(200); }
- collapsed=false;
- }
- }
+function resizeHeight()
+{
+ var headerHeight = header.outerHeight();
+ var footerHeight = footer.outerHeight();
+ var windowHeight = $(window).height() - headerHeight - footerHeight;
+ content.css({height:windowHeight + "px"});
+ navtree.css({height:windowHeight + "px"});
+ sidenav.css({height:windowHeight + "px",top: headerHeight+"px"});
+}
+function initResizable()
+{
header = $("#top");
sidenav = $("#side-nav");
content = $("#doc-content");
navtree = $("#nav-tree");
footer = $("#nav-path");
$(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } });
- $(sidenav).resizable({ minWidth: 0 });
$(window).resize(function() { resizeHeight(); });
- var device = navigator.userAgent.toLowerCase();
- var touch_device = device.match(/(iphone|ipod|ipad|android)/);
- if (touch_device) { /* wider split bar for touch only devices */
- $(sidenav).css({ paddingRight:'20px' });
- $('.ui-resizable-e').css({ width:'20px' });
- $('#nav-sync').css({ right:'34px' });
- barWidth=20;
- }
var width = readCookie('width');
if (width) { restoreWidth(width); } else { resizeWidth(); }
resizeHeight();
@@ -107,8 +76,22 @@ function initResizable()
if (i>=0) window.location.hash=url.substr(i);
var _preventDefault = function(evt) { evt.preventDefault(); };
$("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);
- $(".ui-resizable-handle").dblclick(collapseExpand);
- $(window).load(resizeHeight);
+ $(document).bind('touchmove',function(e){
+ var device = navigator.userAgent.toLowerCase();
+ var ios = device.match(/(iphone|ipod|ipad)/);
+ if (ios) {
+ try {
+ var target = e.target;
+ while (target) {
+ if ($(target).css('-webkit-overflow-scrolling')=='touch') return;
+ target = target.parentNode;
+ }
+ e.preventDefault();
+ } catch(err) {
+ e.preventDefault();
+ }
+ }
+ });
}
diff --git a/extras/html/search/all_0.html b/extras/html/search/all_0.html
index f25360b..c491fd8 100644
--- a/extras/html/search/all_0.html
+++ b/extras/html/search/all_0.html
@@ -1,7 +1,7 @@
-
+
diff --git a/extras/html/search/all_0.js b/extras/html/search/all_0.js
index 747f2f1..0022237 100644
--- a/extras/html/search/all_0.js
+++ b/extras/html/search/all_0.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['arduino_20task_20scheduler',['Arduino Task Scheduler',['../index.html',1,'']]]
+ ['max_5ftask_5fcnt',['MAX_TASK_CNT',['../_tasks_8h.html#a544da5c693eaab178a8138e7ac27ad99',1,'Tasks.h']]]
];
diff --git a/extras/html/search/all_1.html b/extras/html/search/all_1.html
index b13f0f7..89fd5f8 100644
--- a/extras/html/search/all_1.html
+++ b/extras/html/search/all_1.html
@@ -1,7 +1,7 @@
-
+
diff --git a/extras/html/search/all_1.js b/extras/html/search/all_1.js
index 0022237..f986a80 100644
--- a/extras/html/search/all_1.js
+++ b/extras/html/search/all_1.js
@@ -1,4 +1,16 @@
var searchData=
[
- ['max_5ftask_5fcnt',['MAX_TASK_CNT',['../_tasks_8h.html#a544da5c693eaab178a8138e7ac27ad99',1,'Tasks.h']]]
+ ['task',['Task',['../_tasks_8h.html#a43925087945f12bbd3cfd17b6a2a3e13',1,'Tasks.h']]],
+ ['tasks_2ecpp',['Tasks.cpp',['../_tasks_8cpp.html',1,'']]],
+ ['tasks_2eh',['Tasks.h',['../_tasks_8h.html',1,'']]],
+ ['tasks_5fadd',['Tasks_Add',['../_tasks_8cpp.html#abcd73ae8d50ad3929a21a5dfdb269bf4',1,'Tasks_Add(Task func, int16_t period, int16_t delay): Tasks.cpp'],['../_tasks_8h.html#a3e6886beaa41aea1bedede2e0f1c0723',1,'Tasks_Add(Task func, int16_t period, int16_t delay=0): Tasks.cpp']]],
+ ['tasks_5fclear',['Tasks_Clear',['../_tasks_8cpp.html#ad0f9e9096fe29465d37175d88f918370',1,'Tasks_Clear(void): Tasks.cpp'],['../_tasks_8h.html#ad0f9e9096fe29465d37175d88f918370',1,'Tasks_Clear(void): Tasks.cpp']]],
+ ['tasks_5fdelay',['Tasks_Delay',['../_tasks_8cpp.html#a69a28492d0bbe6402e632c04de6f8b40',1,'Tasks_Delay(Task func, int16_t delay): Tasks.cpp'],['../_tasks_8h.html#a69a28492d0bbe6402e632c04de6f8b40',1,'Tasks_Delay(Task func, int16_t delay): Tasks.cpp']]],
+ ['tasks_5finit',['Tasks_Init',['../_tasks_8cpp.html#a5b0ac193b3ae2f2f7cfd5dc7a66c811b',1,'Tasks_Init(void): Tasks.cpp'],['../_tasks_8h.html#a5b0ac193b3ae2f2f7cfd5dc7a66c811b',1,'Tasks_Init(void): Tasks.cpp']]],
+ ['tasks_5fpause',['Tasks_Pause',['../_tasks_8cpp.html#aa5521fb12d15b22fd08dfe78eaf0eabd',1,'Tasks_Pause(void): Tasks.cpp'],['../_tasks_8h.html#aa5521fb12d15b22fd08dfe78eaf0eabd',1,'Tasks_Pause(void): Tasks.cpp']]],
+ ['tasks_5fpause_5ftask',['Tasks_Pause_Task',['../_tasks_8h.html#a359cc9834848534fd2a92f95c16084ed',1,'Tasks.h']]],
+ ['tasks_5fremove',['Tasks_Remove',['../_tasks_8cpp.html#a38461dee754ff5ee43f718fbbad0ed89',1,'Tasks_Remove(Task func): Tasks.cpp'],['../_tasks_8h.html#a38461dee754ff5ee43f718fbbad0ed89',1,'Tasks_Remove(Task func): Tasks.cpp']]],
+ ['tasks_5fsetstate',['Tasks_SetState',['../_tasks_8cpp.html#afeaa615f429dfec3a600104e3777d9ea',1,'Tasks_SetState(Task func, bool state): Tasks.cpp'],['../_tasks_8h.html#afeaa615f429dfec3a600104e3777d9ea',1,'Tasks_SetState(Task func, bool state): Tasks.cpp']]],
+ ['tasks_5fstart',['Tasks_Start',['../_tasks_8cpp.html#aee9e99dc76d2f8ad7c7eb22c6e709271',1,'Tasks_Start(void): Tasks.cpp'],['../_tasks_8h.html#aee9e99dc76d2f8ad7c7eb22c6e709271',1,'Tasks_Start(void): Tasks.cpp']]],
+ ['tasks_5fstart_5ftask',['Tasks_Start_Task',['../_tasks_8h.html#a5cf5713546472be366a7140bcbf5b2fe',1,'Tasks.h']]]
];
diff --git a/extras/html/search/defines_0.html b/extras/html/search/defines_0.html
index 5b25204..27eaf8c 100644
--- a/extras/html/search/defines_0.html
+++ b/extras/html/search/defines_0.html
@@ -1,7 +1,7 @@
-
+
diff --git a/extras/html/search/files_0.html b/extras/html/search/files_0.html
index 4f272b8..0457853 100644
--- a/extras/html/search/files_0.html
+++ b/extras/html/search/files_0.html
@@ -1,7 +1,7 @@
-
+
diff --git a/extras/html/search/functions_0.html b/extras/html/search/functions_0.html
index 4e6d87d..88c8a26 100644
--- a/extras/html/search/functions_0.html
+++ b/extras/html/search/functions_0.html
@@ -1,7 +1,7 @@
-
+
diff --git a/extras/html/search/search.css b/extras/html/search/search.css
index 3cf9df9..4d7612f 100644
--- a/extras/html/search/search.css
+++ b/extras/html/search/search.css
@@ -6,12 +6,14 @@
#MSearchBox {
white-space : nowrap;
+ position: absolute;
float: none;
+ display: inline;
margin-top: 8px;
right: 0px;
width: 170px;
- height: 24px;
z-index: 102;
+ background-color: white;
}
#MSearchBox .left
@@ -46,13 +48,12 @@
height:19px;
background:url('search_m.png') repeat-x;
border:none;
- width:115px;
+ width:111px;
margin-left:20px;
padding-left:4px;
color: #909090;
outline: none;
font: 9pt Arial, Verdana, sans-serif;
- -webkit-border-radius: 0px;
}
#FSearchBox #MSearchField {
@@ -63,7 +64,7 @@
display:block;
position:absolute;
right:10px;
- top:8px;
+ top:0px;
width:20px;
height:19px;
background:url('search_r.png') no-repeat;
@@ -101,7 +102,7 @@
left: 0; top: 0;
border: 1px solid #90A5CE;
background-color: #F9FAFC;
- z-index: 10001;
+ z-index: 1;
padding-top: 4px;
padding-bottom: 4px;
-moz-border-radius: 4px;
@@ -164,7 +165,6 @@ iframe#MSearchResults {
left: 0; top: 0;
border: 1px solid #000;
background-color: #EEF1F7;
- z-index:10000;
}
/* ----------------------------------- */
diff --git a/extras/html/search/searchdata.js b/extras/html/search/searchdata.js
index 7893a6a..145a8ea 100644
--- a/extras/html/search/searchdata.js
+++ b/extras/html/search/searchdata.js
@@ -1,11 +1,10 @@
var indexSectionsWithContent =
{
- 0: "amt",
+ 0: "mt",
1: "t",
2: "t",
3: "t",
- 4: "m",
- 5: "a"
+ 4: "m"
};
var indexSectionNames =
@@ -14,8 +13,7 @@ var indexSectionNames =
1: "files",
2: "functions",
3: "typedefs",
- 4: "defines",
- 5: "pages"
+ 4: "defines"
};
var indexSectionLabels =
@@ -24,7 +22,6 @@ var indexSectionLabels =
1: "Files",
2: "Functions",
3: "Typedefs",
- 4: "Macros",
- 5: "Pages"
+ 4: "Macros"
};
diff --git a/extras/html/search/typedefs_0.html b/extras/html/search/typedefs_0.html
index 05722e1..aad339a 100644
--- a/extras/html/search/typedefs_0.html
+++ b/extras/html/search/typedefs_0.html
@@ -1,7 +1,7 @@
-
+
diff --git a/extras/html/tabs.css b/extras/html/tabs.css
index bbde11e..9cf578f 100644
--- a/extras/html/tabs.css
+++ b/extras/html/tabs.css
@@ -1 +1,60 @@
-.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:transparent}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}}
+.tabs, .tabs2, .tabs3 {
+ background-image: url('tab_b.png');
+ width: 100%;
+ z-index: 101;
+ font-size: 13px;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+.tabs2 {
+ font-size: 10px;
+}
+.tabs3 {
+ font-size: 9px;
+}
+
+.tablist {
+ margin: 0;
+ padding: 0;
+ display: table;
+}
+
+.tablist li {
+ float: left;
+ display: table-cell;
+ background-image: url('tab_b.png');
+ line-height: 36px;
+ list-style: none;
+}
+
+.tablist a {
+ display: block;
+ padding: 0 20px;
+ font-weight: bold;
+ background-image:url('tab_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color: #283A5D;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+ outline: none;
+}
+
+.tabs3 .tablist a {
+ padding: 0 10px;
+}
+
+.tablist a:hover {
+ background-image: url('tab_h.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+ text-decoration: none;
+}
+
+.tablist li.current a {
+ background-image: url('tab_a.png');
+ background-repeat:repeat-x;
+ color: #fff;
+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
diff --git a/src/Tasks.cpp b/src/Tasks.cpp
index c104945..45e61b8 100644
--- a/src/Tasks.cpp
+++ b/src/Tasks.cpp
@@ -1,7 +1,7 @@
/**
- \file Tasks.cpp
- \copybrief Tasks.h
- \details For more details please refer to Tasks.h
+ \file Tasks.cpp
+ \copybrief Tasks.h
+ \details For more details please refer to Tasks.h
*/
#include "Tasks.h"
@@ -9,7 +9,7 @@
// check Arduino controller only once
#if !defined(__AVR__) && !defined(__SAM3X8E__)
- #error board not supported, error
+ #error board not supported, error
#endif
@@ -19,19 +19,19 @@
/// @cond INTERNAL
// measure speed via pin D9(=PB1). Is configured as OUTPUT in Scheduler_Start()
-#define TASKS_MEASURE_PIN 0
+#define TASKS_MEASURE_PIN 0
#if (TASKS_MEASURE_PIN)
- #define SET_PIN (PORTB |= B00000010)
- #define CLEAR_PIN (PORTB &= ~B00000010)
- #define TOGGLE_PIN (PORTB ^= B00000010)
+ #define SET_PIN (PORTB |= B00000010)
+ #define CLEAR_PIN (PORTB &= ~B00000010)
+ #define TOGGLE_PIN (PORTB ^= B00000010)
#endif
// macro to pause / resume interrupt (interrupts are only reactivated in case they have been active in the beginning)
-uint8_t oldISR = 0;
+uint8_t oldISR = 0;
#if defined(__AVR__)
#define PAUSE_INTERRUPTS { oldISR = SREG; noInterrupts(); }
- #define RESUME_INTERRUPTS { SREG = oldISR; interrupts(); }
+ #define RESUME_INTERRUPTS { SREG = oldISR; interrupts(); }
#elif defined(__SAM3X8E__)
#define PAUSE_INTERRUPTS { oldISR = ((__get_PRIMASK() & 0x1) == 0 && (__get_FAULTMASK() & 0x1) == 0); noInterrupts(); }
#define RESUME_INTERRUPTS { if (oldISR != 0) { interrupts(); } }
@@ -41,83 +41,82 @@ uint8_t oldISR = 0;
// task container
struct SchedulingStruct
{
- Task func; // function to call
- bool active; // task is active
- bool running; // task is currently being executed
- int16_t period; // period of task (0 = call only once)
- int16_t time; // time of next call
+ Task func; // function to call
+ bool active; // task is active
+ bool running; // task is currently being executed
+ int16_t period; // period of task (0 = call only once)
+ int16_t time; // time of next call
};
// global variables for scheduler
-struct SchedulingStruct SchedulingTable[MAX_TASK_CNT] = // array containing all tasks
- { {(Task)NULL, false, false, 0, 0} };
-bool SchedulingActive; // false = Scheduling stopped, true = Scheduling active (no configuration allowed)
-int16_t _timebase; // 1ms counter (on ATMega 1.024ms, is compensated)
-int16_t _nexttime; // time of next task call
-uint8_t _lasttask; // last task in the tasks array (cauting! This variable starts is not counting from 0 to x but from 1 to x meaning that a single tasks will be at SchedulingTable[0] but _lasttask will have the value '1')
+struct SchedulingStruct SchedulingTable[MAX_TASK_CNT] = { {(Task)NULL, false, false, 0, 0} }; // array containing all tasks
+bool SchedulingActive; // false = Scheduling stopped, true = Scheduling active (no configuration allowed)
+int16_t _timebase; // 1ms counter (on ATMega 1.024ms, is compensated)
+int16_t _nexttime; // time of next task call
+uint8_t _lasttask; // last task in the tasks array (cauting! This variable starts is not counting from 0 to x but from 1 to x meaning that a single tasks will be at SchedulingTable[0] but _lasttask will have the value '1')
#if defined(__SAM3X8E__)
- /*
- Code from https://forum.arduino.cc/index.php?topic=130423.0
- ISR/IRQ TC Channel Due pins
- TC0 TC0 0 2, 13
- TC1 TC0 1 60, 61
- TC2 TC0 2 58
- TC3 TC1 0 none
- TC4 TC1 1 none
- TC5 TC1 2 none
- TC6 TC2 0 4, 5
- TC7 TC2 1 3, 10
- TC8 TC2 2 11, 12
- */
- void startTasksTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
- {
- pmc_set_writeprotect(false);
- pmc_enable_periph_clk((uint32_t)irq);
- TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
- uint32_t rc = (SystemCoreClock >> 1)/frequency; //2 because we selected TIMER_CLOCK4 above
- //TC_SetRA(tc, channel, (rc >> 1)); //50% high, 50% low
- TC_SetRC(tc, channel, rc);
- TC_Start(tc, channel);
- tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
- tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
- NVIC_SetPriority(SysTick_IRQn, 8);
- NVIC_SetPriority(irq, 15);
- NVIC_EnableIRQ(irq);
- }
+ /*
+ Code from https://forum.arduino.cc/index.php?topic=130423.0
+ ISR/IRQ TC Channel Due pins
+ TC0 TC0 0 2, 13
+ TC1 TC0 1 60, 61
+ TC2 TC0 2 58
+ TC3 TC1 0 none
+ TC4 TC1 1 none
+ TC5 TC1 2 none
+ TC6 TC2 0 4, 5
+ TC7 TC2 1 3, 10
+ TC8 TC2 2 11, 12
+ */
+ void startTasksTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
+ {
+ pmc_set_writeprotect(false);
+ pmc_enable_periph_clk((uint32_t)irq);
+ TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
+ uint32_t rc = (SystemCoreClock >> 1)/frequency; //2 because we selected TIMER_CLOCK4 above
+ //TC_SetRA(tc, channel, (rc >> 1)); //50% high, 50% low
+ TC_SetRC(tc, channel, rc);
+ TC_Start(tc, channel);
+ tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
+ tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
+ NVIC_SetPriority(SysTick_IRQn, 8);
+ NVIC_SetPriority(irq, 15);
+ NVIC_EnableIRQ(irq);
+ }
#endif // __SAM3X8E__
void Scheduler_update_nexttime(void)
{
- // stop interrupts, store old setting
- PAUSE_INTERRUPTS;
-
- // find time of next task execution
- _nexttime = _timebase + INT16_MAX; // Max. possible delay of the next time
- for (uint8_t i = 0; i < _lasttask; i++)
- {
- if ((SchedulingTable[i].active == true) && (SchedulingTable[i].func != NULL))
+ // stop interrupts, store old setting
+ PAUSE_INTERRUPTS;
+
+ // find time of next task execution
+ _nexttime = _timebase + INT16_MAX; // Max. possible delay of the next time
+ for (uint8_t i = 0; i < _lasttask; i++)
{
- //Serial.print(i); Serial.print(" "); Serial.println(SchedulingTable[i].time);
+ if ((SchedulingTable[i].active == true) && (SchedulingTable[i].func != NULL))
+ {
+ //Serial.print(i); Serial.print(" "); Serial.println(SchedulingTable[i].time);
- if ((int16_t)(SchedulingTable[i].time - _nexttime) < 0)
- {
- _nexttime = SchedulingTable[i].time;
- }
+ if ((int16_t)(SchedulingTable[i].time - _nexttime) < 0)
+ {
+ _nexttime = SchedulingTable[i].time;
+ }
+ }
}
- }
- //Serial.print("timebase: "); Serial.println(_timebase);
- //Serial.print("nexttime: "); Serial.println(_nexttime);
- //Serial.println();
+ //Serial.print("timebase: "); Serial.println(_timebase);
+ //Serial.print("nexttime: "); Serial.println(_nexttime);
+ //Serial.println();
- //Serial.print(_timebase); Serial.print(" "); Serial.println(_nexttime - _timebase);
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ //Serial.print(_timebase); Serial.print(" "); Serial.println(_nexttime - _timebase);
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
} // Scheduler_update_nexttime()
@@ -130,13 +129,13 @@ void Scheduler_update_nexttime(void)
void Tasks_Init(void)
{
- /*static bool flagDone = false;
-
- // clear tasks schedule only for first call to avoid issues when calling multiple times
- if (flagDone == false) {
- flagDone = true;
- Tasks_Clear();
- }*/
+ /*static bool flagDone = false;
+
+ // clear tasks schedule only for first call to avoid issues when calling multiple times
+ if (flagDone == false) {
+ flagDone = true;
+ Tasks_Clear();
+ }*/
} // Tasks_Init()
@@ -144,113 +143,113 @@ void Tasks_Init(void)
void Tasks_Clear(void)
{
- uint8_t i;
-
- // stop interrupts, store old setting
- PAUSE_INTERRUPTS;
-
- // init scheduler
- SchedulingActive = false;
- _timebase = 0;
- _nexttime = 0;
- _lasttask = 0;
- for(i = 0; i < MAX_TASK_CNT; i++)
- {
- //Reset scheduling table
- SchedulingTable[i].func = NULL;
- SchedulingTable[i].active = false;
- SchedulingTable[i].running = false;
- SchedulingTable[i].period = 0;
- SchedulingTable[i].time = 0;
- } // loop over scheduler slots
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
-
+ uint8_t i;
+
+ // stop interrupts, store old setting
+ PAUSE_INTERRUPTS;
+
+ // init scheduler
+ SchedulingActive = false;
+ _timebase = 0;
+ _nexttime = 0;
+ _lasttask = 0;
+ for(i = 0; i < MAX_TASK_CNT; i++)
+ {
+ //Reset scheduling table
+ SchedulingTable[i].func = NULL;
+ SchedulingTable[i].active = false;
+ SchedulingTable[i].running = false;
+ SchedulingTable[i].period = 0;
+ SchedulingTable[i].time = 0;
+ } // loop over scheduler slots
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
+
} // Tasks_Clear()
bool Tasks_Add(Task func, int16_t period, int16_t delay)
{
- // Check range of period and delay
- if ((period < 0) || (delay < 0))
- return false;
-
- // workaround for 1.024ms timer period of Arduino ATMega
- #if defined(__AVR__)
- delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8); // delay = delay / 1.024 <-- with up/down rounding
- period = (uint16_t)(((((int32_t)period) * 250) + 128) >> 8); // period = period / 1.024 <-- with up/down rounding
- #endif
-
- // Check if task already exists and update it in this case
- for(uint8_t i = 0; i < _lasttask; i++)
- {
- // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
- PAUSE_INTERRUPTS;
-
- // same function found
- if (SchedulingTable[i].func == func)
+ // Check range of period and delay
+ if ((period < 0) || (delay < 0))
+ return false;
+
+ // workaround for 1.024ms timer period of Arduino ATMega
+ #if defined(__AVR__)
+ delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8); // delay = delay / 1.024 <-- with up/down rounding
+ period = (uint16_t)(((((int32_t)period) * 250) + 128) >> 8); // period = period / 1.024 <-- with up/down rounding
+ #endif
+
+ // Check if task already exists and update it in this case
+ for(uint8_t i = 0; i < _lasttask; i++)
{
- SchedulingTable[i].active = true;
- SchedulingTable[i].running = false;
- SchedulingTable[i].period = period;
- SchedulingTable[i].time = _timebase + delay;
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
-
- // find time for next task execution
- Scheduler_update_nexttime();
-
- // return success
- return true;
- }
+ // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
+ PAUSE_INTERRUPTS;
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ // same function found
+ if (SchedulingTable[i].func == func)
+ {
+ SchedulingTable[i].active = true;
+ SchedulingTable[i].running = false;
+ SchedulingTable[i].period = period;
+ SchedulingTable[i].time = _timebase + delay;
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
+
+ // find time for next task execution
+ Scheduler_update_nexttime();
+
+ // return success
+ return true;
+ }
- } // loop over scheduler slots
-
- // find free scheduler slot
- for (uint8_t i = 0; i < MAX_TASK_CNT; i++)
- {
- // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
- PAUSE_INTERRUPTS;
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- // free slot found
- if (SchedulingTable[i].func == NULL)
+ } // loop over scheduler slots
+
+ // find free scheduler slot
+ for (uint8_t i = 0; i < MAX_TASK_CNT; i++)
{
- // add task to scheduler table
- SchedulingTable[i].func = func;
- SchedulingTable[i].active = true;
- SchedulingTable[i].running = false;
- SchedulingTable[i].period = period;
- SchedulingTable[i].time = _timebase + delay;
-
- // update _lasttask
- if (i >= _lasttask)
- _lasttask = i + 1;
+ // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
+ PAUSE_INTERRUPTS;
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ // free slot found
+ if (SchedulingTable[i].func == NULL)
+ {
+ // add task to scheduler table
+ SchedulingTable[i].func = func;
+ SchedulingTable[i].active = true;
+ SchedulingTable[i].running = false;
+ SchedulingTable[i].period = period;
+ SchedulingTable[i].time = _timebase + delay;
+
+ // update _lasttask
+ if (i >= _lasttask)
+ _lasttask = i + 1;
- // find time for next task execution
- Scheduler_update_nexttime();
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- // return success
- return true;
+ // find time for next task execution
+ Scheduler_update_nexttime();
- } // if free slot found
+ // return success
+ return true;
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ } // if free slot found
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- } // loop over scheduler slots
+ } // loop over scheduler slots
- // did not change anything, thus no scheduler_update_nexttime neccessary
- // no free slot found -> error
- return false;
+ // did not change anything, thus no scheduler_update_nexttime neccessary
+ // no free slot found -> error
+ return false;
} // Tasks_Add()
@@ -258,61 +257,55 @@ bool Tasks_Add(Task func, int16_t period, int16_t delay)
bool Tasks_Remove(Task func)
{
- // stop interrupts, store old setting
- PAUSE_INTERRUPTS;
-
- // find function in scheduler table
- for (uint8_t i = 0; i < _lasttask; i++)
- {
- // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
- PAUSE_INTERRUPTS;
-
- // function pointer found in list
- if (SchedulingTable[i].func == func)
+ // find function in scheduler table
+ for (uint8_t i = 0; i < _lasttask; i++)
{
- // remove task from scheduler table
- SchedulingTable[i].func = NULL;
- SchedulingTable[i].active = false;
- SchedulingTable[i].running = false;
- SchedulingTable[i].period = 0;
- SchedulingTable[i].time = 0;
-
- // update _lasttask
- if (i == (_lasttask - 1))
- {
- _lasttask--;
- while(_lasttask != 0)
+ // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
+ PAUSE_INTERRUPTS;
+
+ // function pointer found in list
+ if (SchedulingTable[i].func == func)
{
- if(SchedulingTable[_lasttask - 1].func != NULL)
- {
- break;
- }
- _lasttask--;
- }
- }
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
-
- // find time for next task execution
- Scheduler_update_nexttime();
-
- // return success
- return true;
-
- } // if function found
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
-
- } // loop over scheduler slots
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
-
- // did not change anything, thus no scheduler_update_nexttime neccessary
- // function not in scheduler -> error
- return false;
+ // remove task from scheduler table
+ SchedulingTable[i].func = NULL;
+ SchedulingTable[i].active = false;
+ SchedulingTable[i].running = false;
+ SchedulingTable[i].period = 0;
+ SchedulingTable[i].time = 0;
+
+ // update _lasttask
+ if (i == (_lasttask - 1))
+ {
+ _lasttask--;
+ while(_lasttask != 0)
+ {
+ if(SchedulingTable[_lasttask - 1].func != NULL)
+ {
+ break;
+ }
+ _lasttask--;
+ }
+ }
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
+
+ // find time for next task execution
+ Scheduler_update_nexttime();
+
+ // return success
+ return true;
+
+ } // if function found
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
+
+ } // loop over scheduler slots
+
+ // did not change anything, thus no scheduler_update_nexttime neccessary
+ // function not in scheduler -> error
+ return false;
} // Tasks_Remove()
@@ -320,138 +313,132 @@ bool Tasks_Remove(Task func)
bool Tasks_Delay(Task func, int16_t delay)
{
- // stop interrupts, store old setting
- PAUSE_INTERRUPTS;
-
- // Check range of delay
- if (delay < 0)
- return false;
-
- // Workaround for 1.024ms timer period of Arduino MEGA
- #if defined(__AVR__)
- delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8); // delay = delay / 1.024 <-- with up/down rounding
- #endif
-
- // find function in scheduler table
- for (uint8_t i = 0; i < _lasttask; i++)
- {
- // stop interrupts, store old setting
- PAUSE_INTERRUPTS;
+ // Check range of delay
+ if (delay < 0)
+ return false;
- // function pointer found in list
- if (SchedulingTable[i].func == func)
- {
- // if task is currently running, delay next call
- if (SchedulingTable[i].running == true)
- SchedulingTable[i].time = SchedulingTable[i].time - SchedulingTable[i].period;
+ // Workaround for 1.024ms timer period of Arduino MEGA
+ #if defined(__AVR__)
+ delay = (uint16_t)(((((int32_t)delay) * 250) + 128) >> 8); // delay = delay / 1.024 <-- with up/down rounding
+ #endif
- // set time to next execution
- SchedulingTable[i].time = _timebase + delay;
+ // find function in scheduler table
+ for (uint8_t i = 0; i < _lasttask; i++)
+ {
+ // stop interrupts, store old setting
+ PAUSE_INTERRUPTS;
+
+ // function pointer found in list
+ if (SchedulingTable[i].func == func)
+ {
+ // if task is currently running, delay next call
+ if (SchedulingTable[i].running == true)
+ SchedulingTable[i].time = SchedulingTable[i].time - SchedulingTable[i].period;
+
+ // set time to next execution
+ SchedulingTable[i].time = _timebase + delay;
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- // find time for next task execution
- Scheduler_update_nexttime();
+ // find time for next task execution
+ Scheduler_update_nexttime();
- // return success
- return true;
+ // return success
+ return true;
- } // if function found
+ } // if function found
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- } // loop over scheduler slots
-
- // did not change anything, thus no scheduler_update_nexttime neccessary
- // function not in scheduler -> error
- return false;
-
+ } // loop over scheduler slots
+
+ // did not change anything, thus no scheduler_update_nexttime neccessary
+ // function not in scheduler -> error
+ return false;
+
} // Tasks_Delay()
bool Tasks_SetState(Task func, bool state)
{
- // stop interrupts, store old setting
- PAUSE_INTERRUPTS;
-
- // find function in scheduler table
- for (uint8_t i = 0; i < _lasttask; i++)
- {
- // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
- PAUSE_INTERRUPTS;
-
- // function pointer found in list
- if(SchedulingTable[i].func == func)
+ // find function in scheduler table
+ for (uint8_t i = 0; i < _lasttask; i++)
{
- // set new function state
- SchedulingTable[i].active = state;
- SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
+ // stop interrupts when accessing any element within the scheduler (also neccessary for if checks!), store old setting
+ PAUSE_INTERRUPTS;
+
+ // function pointer found in list
+ if(SchedulingTable[i].func == func)
+ {
+ // set new function state
+ SchedulingTable[i].active = state;
+ SchedulingTable[i].time = _timebase + SchedulingTable[i].period;
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- // find time for next task execution
- Scheduler_update_nexttime();
+ // find time for next task execution
+ Scheduler_update_nexttime();
- // return success
- return true;
+ // return success
+ return true;
- } // if function found
-
- // resume stored interrupt setting
- RESUME_INTERRUPTS;
+ } // if function found
+
+ // resume stored interrupt setting
+ RESUME_INTERRUPTS;
- } // loop over scheduler slots
-
- // did not change anything, thus no scheduler_update_nexttime neccessary
- // function not in scheduler -> error
- return false;
-
+ } // loop over scheduler slots
+
+ // did not change anything, thus no scheduler_update_nexttime neccessary
+ // function not in scheduler -> error
+ return false;
+
} // Tasks_SetState()
void Tasks_Start(void)
{
- #if (TASKS_MEASURE_PIN)
- pinMode(9, OUTPUT);
- #endif
-
- // enable scheduler
- SchedulingActive = true;
- //_timebase = 0; // unwanted delay after resume, see time-print() output! -> likely delete
-
- _nexttime = _timebase; // Scheduler should perform a full check of all tasks after the next start
-
- // enable timer interrupt
- #if defined(__AVR__)
- TIMSK0 |= (1< likely delete
+
+ _nexttime = _timebase; // Scheduler should perform a full check of all tasks after the next start
+
+ // enable timer interrupt
+ #if defined(__AVR__)
+ TIMSK0 |= (1< likely delete
-
- // disable timer interrupt
- #if defined(__AVR__)
- TIMSK0 &= ~(1< likely delete
+
+ // disable timer interrupt
+ #if defined(__AVR__)
+ TIMSK0 &= ~(1<TC_CHANNEL[0].TC_SR; //Read status register to delete status flags
- #endif
-
- // Skip if scheduling was stopped or is in the process of being stopped
- if (SchedulingActive == false) {
- #if (TASKS_MEASURE_PIN) // measure speed via GPIO
- CLEAR_PIN;
+ uint8_t i;
+
+ // measure speed via GPIO
+ #if (TASKS_MEASURE_PIN)
+ SET_PIN;
#endif
- return;
- }
-
- // increase 1ms counter
- _timebase++;
-
- // no task is pending -> return immediately
- if ((int16_t)(_nexttime - _timebase) > 0) {
- #if (TASKS_MEASURE_PIN) // measure speed via GPIO
- CLEAR_PIN;
+
+ #if defined(__SAM3X8E__)
+ TC1->TC_CHANNEL[0].TC_SR; //Read status register to delete status flags
#endif
- return;
- }
-
- // loop over scheduler slots
- for(i = 0; i < _lasttask; i++)
- {
- // disable interrupts
- noInterrupts();
+
+ // Skip if scheduling was stopped or is in the process of being stopped
+ if (SchedulingActive == false) {
+ #if (TASKS_MEASURE_PIN) // measure speed via GPIO
+ CLEAR_PIN;
+ #endif
+ return;
+ }
+
+ // increase 1ms counter
+ _timebase++;
+
+ // no task is pending -> return immediately
+ if ((int16_t)(_nexttime - _timebase) > 0) {
+ #if (TASKS_MEASURE_PIN) // measure speed via GPIO
+ CLEAR_PIN;
+ #endif
+ return;
+ }
- // function pointer found in list, function is active and not running (arguments ordered to provide maximum speed
- if ((SchedulingTable[i].active == true) && (SchedulingTable[i].running == false) && (SchedulingTable[i].func != NULL))
+ // loop over scheduler slots
+ for(i = 0; i < _lasttask; i++)
{
- // function period has passed
- if((int16_t)(SchedulingTable[i].time - _timebase) <= 0)
- {
- // execute task
- SchedulingTable[i].running = true; // avoid dual function call
- SchedulingTable[i].time = _timebase + SchedulingTable[i].period; // set time of next call
-
- // re-enable interrupts
- interrupts();
-
- // execute function
- SchedulingTable[i].func();
-
// disable interrupts
noInterrupts();
-
- // re-allow function call by scheduler
- SchedulingTable[i].running = false;
-
- // if function period is 0, remove it from scheduler after execution
- if(SchedulingTable[i].period == 0)
+
+ // function pointer found in list, function is active and not running (arguments ordered to provide maximum speed
+ if ((SchedulingTable[i].active == true) && (SchedulingTable[i].running == false) && (SchedulingTable[i].func != NULL))
{
- SchedulingTable[i].func = NULL;
- }
+ // function period has passed
+ if((int16_t)(SchedulingTable[i].time - _timebase) <= 0)
+ {
+ // execute task
+ SchedulingTable[i].running = true; // avoid dual function call
+ SchedulingTable[i].time = _timebase + SchedulingTable[i].period; // set time of next call
+
+ // re-enable interrupts
+ interrupts();
+
+ // execute function
+ SchedulingTable[i].func();
+
+ // disable interrupts
+ noInterrupts();
+
+ // re-allow function call by scheduler
+ SchedulingTable[i].running = false;
+
+ // if function period is 0, remove it from scheduler after execution
+ if(SchedulingTable[i].period == 0)
+ {
+ SchedulingTable[i].func = NULL;
+ }
+
+ // re-enable interrupts
+ interrupts();
+ } // if function period has passed
+ } // if function found
// re-enable interrupts
interrupts();
- } // if function period has passed
- } // if function found
- // re-enable interrupts
- interrupts();
-
- } // loop over scheduler slots
+ } // loop over scheduler slots
- // find time for next task execution
- Scheduler_update_nexttime();
+ // find time for next task execution
+ Scheduler_update_nexttime();
- // measure speed viaGPIO
- #if (TASKS_MEASURE_PIN)
- CLEAR_PIN;
- #endif
-
+ // measure speed viaGPIO
+ #if (TASKS_MEASURE_PIN)
+ CLEAR_PIN;
+ #endif
+
} // ISR()
diff --git a/src/Tasks.h b/src/Tasks.h
index 8499ee0..9b32a53 100644
--- a/src/Tasks.h
+++ b/src/Tasks.h
@@ -1,164 +1,164 @@
/**
- \file Tasks.h
- \brief Library providing a simple task scheduler for multitasking.
- \details This library implements a very basic scheduler that is executed in parallel to the 1ms timer
- interrupt used for the millis() function.
- It enables users to define cyclic tasks or tasks that should be executed in the future in
- parallel to the normal program execution inside the main loop.
- The task scheduler is executed every 1ms.
- The currently running task is always interrupted by this and only continued to be executed
- after all succeeding tasks have finished.
- This means that always the task started last has the highest priority.
- This effect needs to be kept in mind when programming a software using this library.
- Deadlocks can appear when one task waits for another taks which was started before.
- Additionally it is likely that timing critical tasks will not execute properly when they are
- interrupted for too long by other tasks.
- Thus it is recommended to keep the tasks as small and fast as possible.
- The Arduino ATMega (8-bit AVR) leaves the interrupts state shortly after starting the task scheduler which
- makes the scheduler reentrant and allows any other interrupt (timer, UART, etc.) to be triggered.
- The Arduino SAM (32-bit ARM) enables other interrupts by using the lowest possible priority (15) for the
- task scheduler interrupt.
- Warning The Arduino SAM does not support reeantrant interrupts due to HW limitations.
- This means that unlike the Arduino ATMega the DUE is not able to execute fast 1ms tasks several
- times before finishing a slower tasks with for example a 10ms timebase.
- This problem will be especially visible if the sum of the execution time of all tasks is greater
- than the execution period of the fastest task.
- \author Kai Clemens Liebich, Georg Icking-Konert
- \date 2010-11-07
- \version 0.1
+ \file Tasks.h
+ \brief Library providing a simple task scheduler for multitasking.
+ \details This library implements a very basic scheduler that is executed in parallel to the 1ms timer
+ interrupt used for the millis() function.
+ It enables users to define cyclic tasks or tasks that should be executed in the future in
+ parallel to the normal program execution inside the main loop.
+ The task scheduler is executed every 1ms.
+ The currently running task is always interrupted by this and only continued to be executed
+ after all succeeding tasks have finished.
+ This means that always the task started last has the highest priority.
+ This effect needs to be kept in mind when programming a software using this library.
+ Deadlocks can appear when one task waits for another taks which was started before.
+ Additionally it is likely that timing critical tasks will not execute properly when they are
+ interrupted for too long by other tasks.
+ Thus it is recommended to keep the tasks as small and fast as possible.
+ The Arduino ATMega (8-bit AVR) leaves the interrupts state shortly after starting the task scheduler which
+ makes the scheduler reentrant and allows any other interrupt (timer, UART, etc.) to be triggered.
+ The Arduino SAM (32-bit ARM) enables other interrupts by using the lowest possible priority (15) for the
+ task scheduler interrupt.
+ Warning The Arduino SAM does not support reeantrant interrupts due to HW limitations.
+ This means that unlike the Arduino ATMega the DUE is not able to execute fast 1ms tasks several
+ times before finishing a slower tasks with for example a 10ms timebase.
+ This problem will be especially visible if the sum of the execution time of all tasks is greater
+ than the execution period of the fastest task.
+ \author Kai Clemens Liebich, Georg Icking-Konert
+ \date 2019-11-20
+ \version 1.3
*/
/*-----------------------------------------------------------------------------
- MODULE DEFINITION FOR MULTIPLE INCLUSION
+ MODULE DEFINITION FOR MULTIPLE INCLUSION
-----------------------------------------------------------------------------*/
-#ifndef TASKS_H
-#define TASKS_H
+#ifndef TASKS_H
+#define TASKS_H
/*-----------------------------------------------------------------------------
- INCLUDE FILES
+ INCLUDE FILES
-----------------------------------------------------------------------------*/
#include
/*-----------------------------------------------------------------------------
- COMPILER OPTIONS
+ COMPILER OPTIONS
-----------------------------------------------------------------------------*/
#pragma GCC optimize ("O2")
/*-----------------------------------------------------------------------------
- GLOBAL MACROS
+ GLOBAL MACROS
-----------------------------------------------------------------------------*/
-#define MAX_TASK_CNT 8 //!< Maximum number of parallel tasks
-//#define PTR_NON_STATIC_METHOD(instance, method) [instance](){instance.method();} //!< Get pointer to non-static member function via lambda function, see https://stackoverflow.com/questions/53091205/how-to-use-non-static-member-functions-as-callback-in-c
+#define MAX_TASK_CNT 8 //!< Maximum number of parallel tasks
+//#define PTR_NON_STATIC_METHOD(instance, method) [instance](){instance.method();} //!< Get pointer to non-static member function via lambda function, see https://stackoverflow.com/questions/53091205/how-to-use-non-static-member-functions-as-callback-in-c
/*-----------------------------------------------------------------------------
- GLOBAL CLASS
+ GLOBAL CLASS
-----------------------------------------------------------------------------*/
-typedef void (*Task)(void); //!< Example prototype for a function than can be executed as a task
+typedef void (*Task)(void); //!< Example prototype for a function than can be executed as a task
/**
- \brief Initialize timer and reset the tasks scheduler at first call.
- \details This function initializes the related timer and clears the task scheduler at first call.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
+ \brief Initialize timer and reset the tasks scheduler at first call.
+ \details This function initializes the related timer and clears the task scheduler at first call.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
*/
void Tasks_Init(void);
/**
- \brief Reset the tasks schedulder.
- \details This function clears the task scheduler. Use with caution!
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
+ \brief Reset the tasks schedulder.
+ \details This function clears the task scheduler. Use with caution!
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
*/
void Tasks_Clear(void);
/**
- \brief Add a task to the task scheduler.
- \details A new task is added to the scheduler with a given execution period and delay until first execution.
- If no delay is given the task is executed at once or after starting the task scheduler
- (see Tasks_Start())
- If a period of 0ms is given, the task is executed only once and then removed automatically.
- To avoid ambiguities, a function can only be added once to the scheduler.
- Trying to add it a second time will reset and overwrite the settings of the existing task.
- For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
- \param[in] func Function to be executed. The function prototype should be similar to this:
- "void userFunction(void)"
- \param[in] period Execution period of the task in ms (0 to 32767; 0 = task only executes once)
- \param[in] delay Delay until first execution of task in ms (0 to 32767)
- \return true in case of success,
- false in case of failure (max. number of tasks reached, or duplicate function)
- \note The maximum number of tasks is defined as MAX_TASK_CNT in file Tasks.h
+ \brief Add a task to the task scheduler.
+ \details A new task is added to the scheduler with a given execution period and delay until first execution.
+ If no delay is given the task is executed at once or after starting the task scheduler
+ (see Tasks_Start())
+ If a period of 0ms is given, the task is executed only once and then removed automatically.
+ To avoid ambiguities, a function can only be added once to the scheduler.
+ Trying to add it a second time will reset and overwrite the settings of the existing task.
+ For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
+ \param[in] func Function to be executed. The function prototype should be similar to this:
+ "void userFunction(void)"
+ \param[in] period Execution period of the task in ms (0 to 32767; 0 = task only executes once)
+ \param[in] delay Delay until first execution of task in ms (0 to 32767)
+ \return true in case of success,
+ false in case of failure (max. number of tasks reached, or duplicate function)
+ \note The maximum number of tasks is defined as MAX_TASK_CNT in file Tasks.h
*/
bool Tasks_Add(Task func, int16_t period, int16_t delay = 0);
/**
- \brief Remove a task from the task scheduler.
- \details Remove the specified task from the scheduler and free the slot again.
- For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
- \param[in] func Function name that should be removed.
- \return true in case of success,
- false in case of failure (e.g. function not in not in scheduler table)
+ \brief Remove a task from the task scheduler.
+ \details Remove the specified task from the scheduler and free the slot again.
+ For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
+ \param[in] func Function name that should be removed.
+ \return true in case of success,
+ false in case of failure (e.g. function not in not in scheduler table)
*/
bool Tasks_Remove(Task func);
/**
- \brief Delay execution of a task
- \details The task is delayed starting from the last 1ms timer tick which means the delay time
- is accurate to -1ms to 0ms.
- This overwrites any previously set delay setting for this task and thus even allows
- earlier execution of a task.
- Delaying the task by <2ms forces it to be executed during the next 1ms timer tick.
- This means that the task might be called at any time anyway in case it was added multiple
- times to the task scheduler.
- For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
- \param[in] func Function that should be delayed
- \param[in] delay Delay in ms (0 to 32767)
- \return true in case of success,
- false in case of failure (e.g. function not in not in scheduler table)
+ \brief Delay execution of a task
+ \details The task is delayed starting from the last 1ms timer tick which means the delay time
+ is accurate to -1ms to 0ms.
+ This overwrites any previously set delay setting for this task and thus even allows
+ earlier execution of a task.
+ Delaying the task by <2ms forces it to be executed during the next 1ms timer tick.
+ This means that the task might be called at any time anyway in case it was added multiple
+ times to the task scheduler.
+ For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
+ \param[in] func Function that should be delayed
+ \param[in] delay Delay in ms (0 to 32767)
+ \return true in case of success,
+ false in case of failure (e.g. function not in not in scheduler table)
*/
bool Tasks_Delay(Task func, int16_t delay);
/**
- \brief Enable or disable the execution of a task
- \details Temporary pause or resume function for execution of single tasks by scheduler.
- This will not stop the task in case it is currently being executed but just prevents
- the task from being executed again in case its state is set to 'false' (inactive).
- For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
- \param[in] func Function to be paused/resumed.
- The function prototype should be similar to this: "void userFunction(void)"
- \param[in] state New function state (false=pause, true=resume)
- \return 'true' in case of success, else 'false' (e.g. function not in not in scheduler table)
+ \brief Enable or disable the execution of a task
+ \details Temporary pause or resume function for execution of single tasks by scheduler.
+ This will not stop the task in case it is currently being executed but just prevents
+ the task from being executed again in case its state is set to 'false' (inactive).
+ For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
+ \param[in] func Function to be paused/resumed.
+ The function prototype should be similar to this: "void userFunction(void)"
+ \param[in] state New function state (false=pause, true=resume)
+ \return 'true' in case of success, else 'false' (e.g. function not in not in scheduler table)
*/
bool Tasks_SetState(Task func, bool state);
@@ -166,62 +166,62 @@ bool Tasks_SetState(Task func, bool state);
/**
- \brief Activate a task in the scheduler
- \details Resume execution of the specified task. Possible parallel tasks are not affected.
- This is a simple inlined function setting the 'state' argument for Tasks_SetState().
- For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
- \param[in] func Function to be activated
- \return true in case of success,
- false in case of failure (e.g. function not in not in scheduler table)
+ \brief Activate a task in the scheduler
+ \details Resume execution of the specified task. Possible parallel tasks are not affected.
+ This is a simple inlined function setting the 'state' argument for Tasks_SetState().
+ For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
+ \param[in] func Function to be activated
+ \return true in case of success,
+ false in case of failure (e.g. function not in not in scheduler table)
*/
inline bool Tasks_Start_Task(Task func)
- {
- return Tasks_SetState(func, true);
- }
+ {
+ return Tasks_SetState(func, true);
+ }
/**
- \brief Deactivate a task in the scheduler
- \details Pause execution of the specified task. Possible parallel tasks are not affected.
- This is a simple inlined function setting the 'state' argument for Tasks_SetState().
- For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
- \param[in] func Function to be paused
- \return true in case of success,
- false in case of failure (e.g. function not in not in scheduler table)
+ \brief Deactivate a task in the scheduler
+ \details Pause execution of the specified task. Possible parallel tasks are not affected.
+ This is a simple inlined function setting the 'state' argument for Tasks_SetState().
+ For non-static member function use address from PTR_NON_STATIC_METHOD() macro.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
+ \param[in] func Function to be paused
+ \return true in case of success,
+ false in case of failure (e.g. function not in not in scheduler table)
*/
inline bool Tasks_Pause_Task(Task func)
- {
- return Tasks_SetState(func, false);
- }
+ {
+ return Tasks_SetState(func, false);
+ }
/**
- \brief Start the task scheduler
- \details Resume execution of the scheduler. All active tasks are resumed.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
+ \brief Start the task scheduler
+ \details Resume execution of the scheduler. All active tasks are resumed.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
*/
void Tasks_Start(void);
/**
- \brief Pause the task scheduler
- \details Pause execution of the scheduler. All tasks are paused.
-
Used HW blocks:
- - Arduino ATMega: TIMER0_COMPA_vect
- - Arduino SAM: TC3
+ \brief Pause the task scheduler
+ \details Pause execution of the scheduler. All tasks are paused.
+
Used HW blocks:
+ - Arduino ATMega: TIMER0_COMPA_vect
+ - Arduino SAM: TC3
*/
void Tasks_Pause(void);
-#endif //TASKS_H
\ No newline at end of file
+#endif //TASKS_H
\ No newline at end of file