Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a12104b

Browse files
committed
A new approach to identify the presence of register RAMPZ and ENDI and
using Program Counter (PC) greater than 17 bits. Merge from specific branch for test.
1 parent 44f7d7e commit a12104b

File tree

1 file changed

+101
-159
lines changed

1 file changed

+101
-159
lines changed

arduino.DuinOS/DuinOS/port.c

Lines changed: 101 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
332264
portSTACK_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
*/
544486
static 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

Comments
 (0)