4141/* Start tasks with interrupts enabled. */
4242#define portFLAGS_INT_ENABLED ( (StackType_t) 0x80 )
4343
44- #define portSCHEDULER_ISR WDT_vect
44+ #define portSCHEDULER_ISR WDT_vect
4545
4646/*-----------------------------------------------------------*/
4747
@@ -72,16 +72,19 @@ static void prvSetupTimerInterrupt( void );
7272 *
7373 * r0 is set to __tmp_reg__ as the compiler expects it to be thus.
7474 *
75- * #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__ )
75+ * #if defined(__AVR_HAVE_RAMPZ__ )
7676 * #define __RAMPZ__ 0x3B
77+ * #endif
78+ *
79+ * #if defined(__AVR_3_BYTE_PC__)
7780 * #define __EIND__ 0x3C
7881 * #endif
7982 *
8083 * The interrupts will have been disabled during the call to portSAVE_CONTEXT()
8184 * so we need not worry about reading/writing to the stack pointer.
8285 */
83- #if defined(__AVR_ATmega2560__ ) || defined(__AVR_ATmega2561__ )
84- /* 3-Byte PC Save */
86+ #if defined(__AVR_3_BYTE_PC__ ) && defined(__AVR_HAVE_RAMPZ__ )
87+ /* 3-Byte PC Save with RAMPZ */
8588#define portSAVE_CONTEXT () \
8689 __asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
8790 "in __tmp_reg__, __SREG__ \n\t" \
@@ -130,6 +133,54 @@ static void prvSetupTimerInterrupt( void );
130133 "in __tmp_reg__, __SP_H__ \n\t" \
131134 "st x+, __tmp_reg__ \n\t" \
132135 );
136+ #elif defined(__AVR_HAVE_RAMPZ__ )
137+ /* 2-Byte PC Save with RAMPZ */
138+ #define portSAVE_CONTEXT () \
139+ __asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
140+ "in __tmp_reg__, __SREG__ \n\t" \
141+ "cli \n\t" \
142+ "push __tmp_reg__ \n\t" \
143+ "in __tmp_reg__, 0x3B \n\t" \
144+ "push __tmp_reg__ \n\t" \
145+ "push __zero_reg__ \n\t" \
146+ "clr __zero_reg__ \n\t" \
147+ "push r2 \n\t" \
148+ "push r3 \n\t" \
149+ "push r4 \n\t" \
150+ "push r5 \n\t" \
151+ "push r6 \n\t" \
152+ "push r7 \n\t" \
153+ "push r8 \n\t" \
154+ "push r9 \n\t" \
155+ "push r10 \n\t" \
156+ "push r11 \n\t" \
157+ "push r12 \n\t" \
158+ "push r13 \n\t" \
159+ "push r14 \n\t" \
160+ "push r15 \n\t" \
161+ "push r16 \n\t" \
162+ "push r17 \n\t" \
163+ "push r18 \n\t" \
164+ "push r19 \n\t" \
165+ "push r20 \n\t" \
166+ "push r21 \n\t" \
167+ "push r22 \n\t" \
168+ "push r23 \n\t" \
169+ "push r24 \n\t" \
170+ "push r25 \n\t" \
171+ "push r26 \n\t" \
172+ "push r27 \n\t" \
173+ "push r28 \n\t" \
174+ "push r29 \n\t" \
175+ "push r30 \n\t" \
176+ "push r31 \n\t" \
177+ "lds r26, pxCurrentTCB \n\t" \
178+ "lds r27, pxCurrentTCB + 1 \n\t" \
179+ "in __tmp_reg__, __SP_L__ \n\t" \
180+ "st x+, __tmp_reg__ \n\t" \
181+ "in __tmp_reg__, __SP_H__ \n\t" \
182+ "st x+, __tmp_reg__ \n\t" \
183+ );
133184#else
134185/* 2-Byte PC Save */
135186#define portSAVE_CONTEXT () \
@@ -182,8 +233,8 @@ static void prvSetupTimerInterrupt( void );
182233 * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
183234 * the context save so we can write to the stack pointer.
184235 */
185- #if defined(__AVR_ATmega2560__ ) || defined(__AVR_ATmega2561__ )
186- /* 3-Byte PC Restore */
236+ #if defined(__AVR_3_BYTE_PC__ ) && defined(__AVR_HAVE_RAMPZ__ )
237+ /* 3-Byte PC Restore with RAMPZ */
187238#define portRESTORE_CONTEXT () \
188239 __asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
189240 "lds r27, pxCurrentTCB + 1 \n\t" \
@@ -230,6 +281,52 @@ static void prvSetupTimerInterrupt( void );
230281 "out __SREG__, __tmp_reg__ \n\t" \
231282 "pop __tmp_reg__ \n\t" \
232283 );
284+ #elif defined(__AVR_HAVE_RAMPZ__ )
285+ /* 2-Byte PC Restore with RAMPZ */
286+ #define portRESTORE_CONTEXT () \
287+ __asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
288+ "lds r27, pxCurrentTCB + 1 \n\t" \
289+ "ld r28, x+ \n\t" \
290+ "out __SP_L__, r28 \n\t" \
291+ "ld r29, x+ \n\t" \
292+ "out __SP_H__, r29 \n\t" \
293+ "pop r31 \n\t" \
294+ "pop r30 \n\t" \
295+ "pop r29 \n\t" \
296+ "pop r28 \n\t" \
297+ "pop r27 \n\t" \
298+ "pop r26 \n\t" \
299+ "pop r25 \n\t" \
300+ "pop r24 \n\t" \
301+ "pop r23 \n\t" \
302+ "pop r22 \n\t" \
303+ "pop r21 \n\t" \
304+ "pop r20 \n\t" \
305+ "pop r19 \n\t" \
306+ "pop r18 \n\t" \
307+ "pop r17 \n\t" \
308+ "pop r16 \n\t" \
309+ "pop r15 \n\t" \
310+ "pop r14 \n\t" \
311+ "pop r13 \n\t" \
312+ "pop r12 \n\t" \
313+ "pop r11 \n\t" \
314+ "pop r10 \n\t" \
315+ "pop r9 \n\t" \
316+ "pop r8 \n\t" \
317+ "pop r7 \n\t" \
318+ "pop r6 \n\t" \
319+ "pop r5 \n\t" \
320+ "pop r4 \n\t" \
321+ "pop r3 \n\t" \
322+ "pop r2 \n\t" \
323+ "pop __zero_reg__ \n\t" \
324+ "pop __tmp_reg__ \n\t" \
325+ "out 0x3B, __tmp_reg__ \n\t" \
326+ "pop __tmp_reg__ \n\t" \
327+ "out __SREG__, __tmp_reg__ \n\t" \
328+ "pop __tmp_reg__ \n\t" \
329+ );
233330#else
234331/* 2-Byte PC Restore */
235332#define portRESTORE_CONTEXT () \
@@ -301,7 +398,7 @@ uint16_t usAddress;
301398 /* The start of the task code will be popped off the stack last, so place
302399 it on first. */
303400
304- #if defined(__AVR_ATmega2560__ ) || defined( __AVR_ATmega2561__ )
401+ #if defined(__AVR_3_BYTE_PC__ )
305402 /* The AVR ATmega2560/ATmega2561 have 256KBytes of program memory and a 17-bit
306403 * program counter. When a code address is stored on the stack, it takes 3 bytes
307404 * instead of 2 for the other ATmega* chips.
@@ -341,16 +438,20 @@ uint16_t usAddress;
341438 * pxTopOfStack = portFLAGS_INT_ENABLED ;
342439 pxTopOfStack -- ;
343440
344- #if defined(__AVR_ATmega2560__ ) || defined(__AVR_ATmega2561__ )
345-
346- /* If we have an ATmega256x, we are also saving the RAMPZ and EIND registers.
347- * We should default those to 0.
441+ #if defined(__AVR_3_BYTE_PC__ )
442+ /* If we have an ATmega256x, we are also saving the EIND register.
443+ * We should default to 0.
348444 */
349445 * pxTopOfStack = ( StackType_t ) 0x00 ; /* EIND */
350446 pxTopOfStack -- ;
447+ #endif
448+
449+ #if defined(__AVR_HAVE_RAMPZ__ )
450+ /* We are saving the RAMPZ register.
451+ * We should default to 0.
452+ */
351453 * pxTopOfStack = ( StackType_t ) 0x00 ; /* RAMPZ */
352454 pxTopOfStack -- ;
353-
354455#endif
355456
356457 /* Now the remaining registers. The compiler expects R1 to be 0. */
@@ -479,7 +580,7 @@ void vPortYieldFromTick( void )
479580{
480581 portSAVE_CONTEXT ();
481582
482- sleep_reset (); // reset the sleep_mode() faster than sleep_disable();
583+ sleep_reset (); // reset the sleep_mode() faster than sleep_disable();
483584
484585 if ( xTaskIncrementTick () != pdFALSE )
485586 {
@@ -492,13 +593,15 @@ void vPortYieldFromTick( void )
492593}
493594/*-----------------------------------------------------------*/
494595
495- //initialize watchdog
596+ /*
597+ * Setup WDT to generate a tick interrupt.
598+ */
496599void prvSetupTimerInterrupt ( void )
497600{
498- // reset watchdog
601+ /* reset watchdog */
499602 wdt_reset ();
500603
501- // set up WDT Interrupt (rather than the WDT Reset).
604+ /* set up WDT Interrupt (rather than the WDT Reset). */
502605 wdt_interrupt_enable ( portUSE_WDTO );
503606}
504607
@@ -515,14 +618,15 @@ void prvSetupTimerInterrupt( void )
515618 *
516619 */
517620 ISR (portSCHEDULER_ISR , ISR_NAKED ) __attribute__ ((hot , flatten ));
518- // ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
621+ /* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
622+ */
519623 ISR (portSCHEDULER_ISR )
520624 {
521625 vPortYieldFromTick ();
522626 __asm__ __volatile__ ( "reti" );
523627 }
524-
525628#else
629+
526630 /*
527631 * Tick ISR for the cooperative scheduler. All this does is increment the
528632 * tick count. We don't need to switch context, this can only be done by
@@ -531,10 +635,10 @@ void prvSetupTimerInterrupt( void )
531635 * use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
532636 */
533637 ISR (portSCHEDULER_ISR ) __attribute__ ((hot , flatten ));
534- // ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
638+ /* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
639+ */
535640 ISR (portSCHEDULER_ISR )
536641 {
537642 xTaskIncrementTick ();
538643 }
539-
540- #endif // configUSE_PREEMPTION
644+ #endif
0 commit comments