@@ -86,7 +86,7 @@ Changes from V2.6.0
8686
8787#include "FreeRTOS.h"
8888#include "task.h"
89- #include "wiring_private.h"
89+ #include "wiring_private.h"
9090
9191/*-----------------------------------------------------------
9292 * Implementation of functions defined in portable.h for the AVR port.
@@ -125,62 +125,27 @@ extern volatile tskTCB * volatile pxCurrentTCB;
125125 * The interrupts will have been disabled during the call to portSAVE_CONTEXT()
126126 * so we need not worry about reading/writing to the stack pointer.
127127 */
128- #if defined(__AVR_ATmega2560__ )
129128#define portSAVE_CONTEXT () \
130129 asm volatile ( "push r0 \n\t" \
131130 "in r0, __SREG__ \n\t" \
132131 "cli \n\t" \
133132 "push r0 \n\t" \
134- "in r0, 0x3b \n\t" \
133+ );
134+ /* CDCP - begin*/
135+ #if defined(__AVR_HAVE_RAMPZ__ )
136+ /*
137+ * have RAMPZ Extended Z-pointer Register for ELPM/SPM
138+ * the uC have extend program memory
139+ * 0x3b --> RAMPZ
140+ * 0x3c --> EIND
141+ */
142+ asm volatile ( "in r0, 0x3b \n\t" \
135143 "push r0 \n\t" \
136144 "in r0, 0x3c \n\t" \
137145 "push r0 \n\t" \
138- "push r1 \n\t" \
139- "clr r1 \n\t" \
140- "push r2 \n\t" \
141- "push r3 \n\t" \
142- "push r4 \n\t" \
143- "push r5 \n\t" \
144- "push r6 \n\t" \
145- "push r7 \n\t" \
146- "push r8 \n\t" \
147- "push r9 \n\t" \
148- "push r10 \n\t" \
149- "push r11 \n\t" \
150- "push r12 \n\t" \
151- "push r13 \n\t" \
152- "push r14 \n\t" \
153- "push r15 \n\t" \
154- "push r16 \n\t" \
155- "push r17 \n\t" \
156- "push r18 \n\t" \
157- "push r19 \n\t" \
158- "push r20 \n\t" \
159- "push r21 \n\t" \
160- "push r22 \n\t" \
161- "push r23 \n\t" \
162- "push r24 \n\t" \
163- "push r25 \n\t" \
164- "push r26 \n\t" \
165- "push r27 \n\t" \
166- "push r28 \n\t" \
167- "push r29 \n\t" \
168- "push r30 \n\t" \
169- "push r31 \n\t" \
170- "lds r26, pxCurrentTCB \n\t" \
171- "lds r27, pxCurrentTCB + 1 \n\t" \
172- "in r0, 0x3d \n\t" \
173- "st x+, r0 \n\t" \
174- "in r0, 0x3e \n\t" \
175- "st x+, r0 \n\t" \
176146 );
177- #else
178- #define portSAVE_CONTEXT () \
179- asm volatile ( "push r0 \n\t" \
180- "in r0, __SREG__ \n\t" \
181- "cli \n\t" \
182- "push r0 \n\t" \
183- "push r1 \n\t" \
147+ #endif
148+ asm volatile ( "push r1 \n\t" \
184149 "clr r1 \n\t" \
185150 "push r2 \n\t" \
186151 "push r3 \n\t" \
@@ -219,14 +184,13 @@ extern volatile tskTCB * volatile pxCurrentTCB;
219184 "in r0, 0x3e \n\t" \
220185 "st x+, r0 \n\t" \
221186 );
222- #endif
187+
223188
224189/*
225190 * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
226191 * the context save so we can write to the stack pointer.
227192 */
228193
229- #if defined(__AVR_ATmega2560__ )
230194#define portRESTORE_CONTEXT () \
231195 asm volatile ( "lds r26, pxCurrentTCB \n\t" \
232196 "lds r27, pxCurrentTCB + 1 \n\t" \
@@ -266,57 +230,25 @@ extern volatile tskTCB * volatile pxCurrentTCB;
266230 "pop r2 \n\t" \
267231 "pop r1 \n\t" \
268232 "pop r0 \n\t" \
269- "out 0x3c, r0 \n\t" \
233+ );
234+
235+ #if defined(__AVR_HAVE_RAMPZ__ )
236+ /*
237+ * have RAMPZ Extended Z-pointer Register for ELPM/SPM
238+ * the uC have extend program memory
239+ * 0x3b --> RAMPZ
240+ * 0x3c --> EIND
241+ */
242+ asm volatile ( "out 0x3c, r0 \n\t" \
270243 "pop r0 \n\t" \
271244 "out 0x3b, r0 \n\t" \
272245 "pop r0 \n\t" \
273- "out __SREG__, r0 \n\t" \
274- "pop r0 \n\t" \
275246 );
276- #else
277- #define portRESTORE_CONTEXT () \
278- asm volatile ( "lds r26, pxCurrentTCB \n\t" \
279- "lds r27, pxCurrentTCB + 1 \n\t" \
280- "ld r28, x+ \n\t" \
281- "out __SP_L__, r28 \n\t" \
282- "ld r29, x+ \n\t" \
283- "out __SP_H__, r29 \n\t" \
284- "pop r31 \n\t" \
285- "pop r30 \n\t" \
286- "pop r29 \n\t" \
287- "pop r28 \n\t" \
288- "pop r27 \n\t" \
289- "pop r26 \n\t" \
290- "pop r25 \n\t" \
291- "pop r24 \n\t" \
292- "pop r23 \n\t" \
293- "pop r22 \n\t" \
294- "pop r21 \n\t" \
295- "pop r20 \n\t" \
296- "pop r19 \n\t" \
297- "pop r18 \n\t" \
298- "pop r17 \n\t" \
299- "pop r16 \n\t" \
300- "pop r15 \n\t" \
301- "pop r14 \n\t" \
302- "pop r13 \n\t" \
303- "pop r12 \n\t" \
304- "pop r11 \n\t" \
305- "pop r10 \n\t" \
306- "pop r9 \n\t" \
307- "pop r8 \n\t" \
308- "pop r7 \n\t" \
309- "pop r6 \n\t" \
310- "pop r5 \n\t" \
311- "pop r4 \n\t" \
312- "pop r3 \n\t" \
313- "pop r2 \n\t" \
314- "pop r1 \n\t" \
315- "pop r0 \n\t" \
316- "out __SREG__, r0 \n\t" \
247+ #endif
248+
249+ asm volatile ( "out __SREG__, r0 \n\t" \
317250 "pop r0 \n\t" \
318251 );
319- #endif
320252
321253/*-----------------------------------------------------------*/
322254
@@ -331,10 +263,12 @@ static void prvSetupTimerInterrupt( void );
331263 */
332264portSTACK_TYPE * pxPortInitialiseStack ( portSTACK_TYPE * pxTopOfStack , pdTASK_CODE pxCode , void * pvParameters )
333265{
334- #if defined(__AVR_ATmega2560__ )
335- /* ATmega2560 DuinOS port by SkyWodd
336- * Corrected by NiesteSzeck*/
266+ /* CDCP
267+ * __AVR_3_BYTE_PC__ is not official, and only exist after version 4.1 of GCC
268+ */
269+ #if defined(__AVR_HAVE_RAMPZ__ ) || defined(__AVR_3_BYTE_PC__ )
337270 unsigned portLONG usAddress ; // ATMega2560 have 17bit Program Counter register
271+ // Other future uControler can have up 22, or 24 bits.
338272#else
339273 unsigned portSHORT usAddress ; // over ATmega have 16bit Program Counter register
340274#endif
@@ -355,33 +289,36 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
355289
356290 /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
357291
358- #if defined(__AVR_ATmega2560__ )
359- // Implement normal stack initialisation but with portLONG instead of portSHORT
360- usAddress = ( unsigned portLONG ) pxCode ;
361- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff );
362- pxTopOfStack -- ;
363-
364- usAddress >>= 8 ;
365- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff );
366- pxTopOfStack -- ;
367-
368- // Implemented the 3byte addressing
369- usAddress >>= 8 ;
370- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff );
371- pxTopOfStack -- ;
372-
373- // Normal initialisation for over ATmega
374- #else
292+ /* CDCP
293+ * __AVR_3_BYTE_PC__ is not official
294+ */
295+ #if defined(__AVR_HAVE_RAMPZ__ ) || defined(__AVR_3_BYTE_PC__ )
296+ // Implement normal stack initialisation but with portLONG instead of portSHORT
297+ usAddress = ( unsigned portLONG ) pxCode ;
298+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff );
299+ pxTopOfStack -- ;
300+
301+ usAddress >>= 8 ;
302+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff );
303+ pxTopOfStack -- ;
304+
305+ // Implemented the 3byte addressing
306+ usAddress >>= 8 ;
307+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff );
308+ pxTopOfStack -- ;
309+
310+ // Normal initialisation for over ATmega
311+ #else
375312 /* The start of the task code will be popped off the stack last, so place
376313 it on first. */
377- usAddress = ( unsigned portSHORT ) pxCode ;
378- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
314+ usAddress = ( unsigned portSHORT ) pxCode ;
315+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
379316 pxTopOfStack -- ;
380317
381318 usAddress >>= 8 ;
382- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
319+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
383320 pxTopOfStack -- ;
384- #endif
321+ #endif
385322
386323 /* Next simulate the stack as if after a call to portSAVE_CONTEXT().
387324 portSAVE_CONTEXT places the flags on the stack immediately after r0
@@ -392,7 +329,12 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
392329 * pxTopOfStack = portFLAGS_INT_ENABLED ;
393330 pxTopOfStack -- ;
394331
395- #if defined(__AVR_ATmega2560__ )
332+ /* CDCP - begin*/
333+ #if defined(__AVR_HAVE_RAMPZ__ )
334+ /*
335+ * have RAMPZ Extended Z-pointer Register for ELPM/SPM
336+ * the uC have extend program memory
337+ */
396338
397339 /* The Atmega2560 has two more register that we are saving
398340 * The EIND and RAMPZ and we are going to initialize
@@ -454,12 +396,12 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
454396 pxTopOfStack -- ;
455397
456398 /* Place the parameter on the stack in the expected location. */
457- usAddress = ( unsigned portSHORT ) pvParameters ;
458- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
399+ usAddress = ( unsigned portSHORT ) pvParameters ;
400+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
459401 pxTopOfStack -- ;
460402
461403 usAddress >>= 8 ;
462- * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
404+ * pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
463405 pxTopOfStack -- ;
464406
465407 * pxTopOfStack = ( portSTACK_TYPE ) 0x26 ; /* R26 X */
@@ -543,42 +485,42 @@ void vPortYieldFromTick( void )
543485 */
544486static void prvSetupTimerInterrupt ( void )
545487{
546- // on the ATmega168, timer 0 is also used for fast hardware pwm
547- // (using phase-correct PWM would mean that timer 0 overflowed half as often
548- // resulting in different millis() behavior on the ATmega8 and ATmega168)
549- #if defined(TCCR0A ) && defined(WGM01 )
550- sbi (TCCR0A , WGM01 );
551- sbi (TCCR0A , WGM00 );
552- #endif
553-
554- // set timer 0 prescale factor to 64
555- #if defined(__AVR_ATmega128__ )
556- // CPU specific: different values for the ATmega128
557- sbi (TCCR0 , CS02 );
558- #elif defined(TCCR0 ) && defined(CS01 ) && defined(CS00 )
559- // this combination is for the standard atmega8
560- sbi (TCCR0 , CS01 );
561- sbi (TCCR0 , CS00 );
562- #elif defined(TCCR0B ) && defined(CS01 ) && defined(CS00 )
563- // this combination is for the standard 168/328/1280/2560
564- sbi (TCCR0B , CS01 );
565- sbi (TCCR0B , CS00 );
566- #elif defined(TCCR0A ) && defined(CS01 ) && defined(CS00 )
567- // this combination is for the __AVR_ATmega645__ series
568- sbi (TCCR0A , CS01 );
569- sbi (TCCR0A , CS00 );
570- #else
571- #error Timer 0 prescale factor 64 not set correctly
572- #endif
573-
574- // enable timer 0 overflow interrupt
575- #if defined(TIMSK ) && defined(TOIE0 )
576- sbi (TIMSK , TOIE0 );
577- #elif defined(TIMSK0 ) && defined(TOIE0 )
578- sbi (TIMSK0 , TOIE0 );
579- #else
580- #error Timer 0 overflow interrupt not set correctly
581- #endif
488+ // on the ATmega168, timer 0 is also used for fast hardware pwm
489+ // (using phase-correct PWM would mean that timer 0 overflowed half as often
490+ // resulting in different millis() behavior on the ATmega8 and ATmega168)
491+ #if defined(TCCR0A ) && defined(WGM01 )
492+ sbi (TCCR0A , WGM01 );
493+ sbi (TCCR0A , WGM00 );
494+ #endif
495+
496+ // set timer 0 prescale factor to 64
497+ #if defined(__AVR_ATmega128__ )
498+ // CPU specific: different values for the ATmega128
499+ sbi (TCCR0 , CS02 );
500+ #elif defined(TCCR0 ) && defined(CS01 ) && defined(CS00 )
501+ // this combination is for the standard atmega8
502+ sbi (TCCR0 , CS01 );
503+ sbi (TCCR0 , CS00 );
504+ #elif defined(TCCR0B ) && defined(CS01 ) && defined(CS00 )
505+ // this combination is for the standard 168/328/1280/2560
506+ sbi (TCCR0B , CS01 );
507+ sbi (TCCR0B , CS00 );
508+ #elif defined(TCCR0A ) && defined(CS01 ) && defined(CS00 )
509+ // this combination is for the __AVR_ATmega645__ series
510+ sbi (TCCR0A , CS01 );
511+ sbi (TCCR0A , CS00 );
512+ #else
513+ #error Timer 0 prescale factor 64 not set correctly
514+ #endif
515+
516+ // enable timer 0 overflow interrupt
517+ #if defined(TIMSK ) && defined(TOIE0 )
518+ sbi (TIMSK , TOIE0 );
519+ #elif defined(TIMSK0 ) && defined(TOIE0 )
520+ sbi (TIMSK0 , TOIE0 );
521+ #else
522+ #error Timer 0 overflow interrupt not set correctly
523+ #endif
582524}
583525/*-----------------------------------------------------------*/
584526
0 commit comments