Skip to content

Commit

Permalink
🚀 finish up AVR support
Browse files Browse the repository at this point in the history
  • Loading branch information
EDI-Systems committed May 24, 2024
1 parent 33eaa51 commit 50f39cc
Show file tree
Hide file tree
Showing 24 changed files with 825 additions and 211 deletions.
24 changes: 19 additions & 5 deletions Include/Platform/AVR/Chip/ATMEGA1284P/rmp_platform_atmega1284p.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Description: The configuration file for ATMEGA1284P.
#define RMP_INT_MASK() RMP_Int_Disable()
#define RMP_INT_UNMASK() RMP_Int_Enable()

/* What is the Systick value? */
/* What is the Systick value? 50U = 12800 cycles = 0.8ms */
#define RMP_AVR_TICK_VAL (50U)
/* Does the chip have RAMP, EIND, and is it XMEGA? */
#define RMP_AVR_COP_RAMP (1U)
Expand All @@ -41,18 +41,32 @@ Description: The configuration file for ATMEGA1284P.
#define RMP_AVR_LOWLVL_INIT() \
do \
{ \
/* No need to set clock because we have fuse bits */ \
\
/* Initialize serial */ \
/* USART0 TX pin - PD1 */ \
DDRD=0x02U; \
/* USART0 - double speed, TX only, 115200-8-N-1 */ \
UCSR0A=0x02U; \
UCSR0B=0x08U; \
UCSR0C=0x06U; \
UBRR0=16U; \
/* Timer 0 - CTC mode, UP counter, prescaler 256 */ \
TCNT0=0x00U; \
OCR0A=RMP_AVR_TICK_VAL; \
TIFR0=0x00U; \
TCCR0A=0x02U; \
TCCR0B=0x04U; \
TIMSK0=0x02U; \
} \
while(0)

#define RMP_AVR_TIM_CLR()
#define RMP_AVR_TIM_CLR() (TIFR0=0x00U)

/* This is for debugging output */
#define RMP_AVR_PUTCHAR(CHAR) \
do \
{ \
/* Wait for transmit buffer to be empty */ \
while((UCSR0A&0x20U)==0U); \
UDR0=(CHAR); \
} \
while(0)
/* End Define ****************************************************************/
Expand Down
25 changes: 21 additions & 4 deletions Include/Platform/AVR/Chip/ATMEGA2560/rmp_platform_atmega2560.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Description: The configuration file for ATMEGA2560.
******************************************************************************/

/* Define ********************************************************************/
/* The HAL library */
/* The AVR I/O library */
#include "avr/io.h"

/* Debugging */
Expand All @@ -27,8 +27,8 @@ Description: The configuration file for ATMEGA2560.
#define RMP_INT_MASK() RMP_Int_Disable()
#define RMP_INT_UNMASK() RMP_Int_Enable()

/* What is the Systick value? */
#define RMP_AVR_TICK_VAL (2000U)
/* What is the Systick value? 50U = 12800 cycles = 0.8ms */
#define RMP_AVR_TICK_VAL (50U)
/* Does the chip have RAMP, EIND, and is it XMEGA? */
#define RMP_AVR_COP_RAMP (1U)
#define RMP_AVR_COP_EIND (1U)
Expand All @@ -41,15 +41,32 @@ Description: The configuration file for ATMEGA2560.
#define RMP_AVR_LOWLVL_INIT() \
do \
{ \
/* USART0 TX pin - PE1 */ \
DDRE=0x02U; \
/* USART0 - double speed, TX only, 115200-8-N-1 */ \
UCSR0A=0x02U; \
UCSR0B=0x08U; \
UCSR0C=0x06U; \
UBRR0=16U; \
/* Timer 0 - CTC mode, UP counter, prescaler 256 */ \
TCNT0=0x00U; \
OCR0A=RMP_AVR_TICK_VAL; \
TIFR0=0x00U; \
TCCR0A=0x02U; \
TCCR0B=0x04U; \
TIMSK0=0x02U; \
} \
while(0)

#define RMP_AVR_TIM_CLR()
#define RMP_AVR_TIM_CLR() (TIFR0=0x00U)

/* This is for debugging output */
#define RMP_AVR_PUTCHAR(CHAR) \
do \
{ \
/* Wait for transmit buffer to be empty */ \
while((UCSR0A&0x20U)==0U); \
UDR0=(CHAR); \
} \
while(0)
/* End Define ****************************************************************/
Expand Down
16 changes: 13 additions & 3 deletions Include/Platform/AVR/rmp_platform_avr.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ Date : 01/04/2017
Licence : The Unlicense; see LICENSE for details.
Description : The header of "rmp_platform_avr.c".
This port supports both MegaAVR and XMegaAVR but not TinyAVR.
Supported cores include AVRe, AVRe+, AVRxm and AVRxt.
Please refrain from trying to use this port on chips that has
less than 32kB of Flash, because the kernel uses about 16kB.
In contrast, the IAR compiler is expected to generate less code
through the extensive use of static overlay (rather than the GCC
software stack as most 8-bitters lack SP-relative addressing),
however this scheme precludes the porting of the kernel.
This port is supplied as a proof of existence of RMP on even
8-bit devices rather than to be used in a production setting.
8-bit devices rather than to be used in a production setting;
AVR is not particularly great in term of code density when
compared with other 8-bitters such as PIC, STM8, and even 8051.
All kernel functions assume zero for all RAMP/EIND segment
registers; still, they are saved and restored as a part of the
context switch, and are cleared before calling any ISR written
in C. This is in accordance with the GCC's use of these registers,
and the user is responsible for clearing them when they are
changed before calling the kernel APIs.
******************************************************************************/

/* Define ********************************************************************/
Expand Down Expand Up @@ -151,11 +160,12 @@ struct RMP_AVR_Stack
rmp_u8_t R29_YH;
rmp_u8_t R30_ZL;
rmp_u8_t R31_ZH;
rmp_u8_t PCL;
rmp_u8_t PCH;
/* Big-endian for CALL and interrupt entry PC */
#if(RMP_AVR_COP_EIND!=0U)
rmp_u8_t PCU;
#endif
rmp_u8_t PCH;
rmp_u8_t PCL;
};
/*****************************************************************************/
/* __RMP_PLATFORM_AVR_STRUCT__ */
Expand Down
61 changes: 25 additions & 36 deletions Include/Platform/AVR/rmp_platform_avr_gcc.inc
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
.extern _RMP_AVR_SP_Kern
/* The current thread stack */
.extern RMP_SP_Cur
;The interrupt active flag
/* The interrupt active flag */
.extern RMP_AVR_Int_Act
;The yield pending flag
/* The yield pending flag */
.extern _RMP_AVR_Yield_Pend
;Extract highest priority running thread
/* Extract highest priority running thread */
.extern _RMP_Run_High
;Handler for DSPIC timer interrupt
/* Handler for DSPIC timer interrupt */
.extern _RMP_AVR_Tim_Handler
/* End Import ****************************************************************/

Expand Down Expand Up @@ -79,45 +79,34 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and

/* Actual context switch *****************************************************/
.macro RMP_AVR_SWITCH_PRE
IN R18,RMP_SPL /* Save the SP to control block */
IN R19,RMP_SPH
LDI R28,lo8(RMP_SP_Cur) /* Y[29:28] is Callee-save */
LDI R29,hi8(RMP_SP_Cur)
ST Y,R18
STD Y+1,R19
LDI R30,lo8(_RMP_AVR_SP_Kern) /* Load SP for kernel */
LDI R31,hi8(_RMP_AVR_SP_Kern)
LD R18,Z
LDD R19,Z+1
OUT RMP_SPL,R18
IN R19,RMP_SPH /* Save the SP to control block */
IN R18,RMP_SPL
STS RMP_SP_Cur+1,R19
STS RMP_SP_Cur,R18
LDS R19,_RMP_AVR_SP_Kern+1 /* Load SP for kernel */
LDS R18,_RMP_AVR_SP_Kern
OUT RMP_SPH,R19
LDI R30,lo8(RMP_AVR_Int_Act) /* Indicate interrupt active */
LDI R31,hi8(RMP_AVR_Int_Act)
LDI R18,1
ST Z,R18
OUT RMP_SPL,R18
LDI R18,1 /* Indicate interrupt active */
STS RMP_AVR_Int_Act,R18
EOR R1,R1 /* Clear implicit zero register */
.endm

/* Actual context switch *****************************************************/
.macro RMP_AVR_SWITCH_POST
LDI R30,lo8(_RMP_AVR_Yield_Pend)
LDI R31,hi8(_RMP_AVR_Yield_Pend)
LD R18,Z
LDS R18,_RMP_AVR_Yield_Pend
CPI R18,0
BREQ 1f
LDI R18,0
ST Z,R18
LDI R30,lo8(_RMP_Run_High)
LDI R31,hi8(_RMP_Run_High)
ICALL
EOR R18,R18
STS _RMP_AVR_Yield_Pend,R18
CALL _RMP_Run_High /* No need to clean R1 again */
1:
LDI R30,lo8(RMP_AVR_Int_Act)
LDI R31,hi8(RMP_AVR_Int_Act)
LDI R18,0
ST Z,R18
LD R18,Y /* Load the SP from control block */
LDD R19,Y+1 /* Y[29:28] is Callee-save */
OUT RMP_SPL,R18
EOR R18,R18
STS RMP_AVR_Int_Act,R18
LDS R19,RMP_SP_Cur+1 /* Load the SP from control block */
LDS R18,RMP_SP_Cur
OUT RMP_SPH,R19
OUT RMP_SPL,R18
.endm

/* Restore all GP regs *******************************************************/
Expand Down Expand Up @@ -169,7 +158,7 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
PUSH R20
PUSH R19
PUSH R18
LDI R18,0x00
EOR R18,R18
OUT RMP_RAMPD,R18
OUT RMP_RAMPX,R18
OUT RMP_RAMPY,R18
Expand All @@ -192,7 +181,7 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
.macro RMP_AVR_EIND_SAVE
IN R18,RMP_EIND
PUSH R18
LDI R18,0x00
EOR R18,R18
OUT RMP_EIND,R18
.endm

Expand Down
52 changes: 51 additions & 1 deletion Include/Test/Chip/rmp_test_atmega1284p.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,45 @@ Author : pry
Date : 22/07/2017
Licence : The Unlicense; see LICENSE for details.
Description : The testbench for ATMEGA1284P.
This test takes 1 min @16 MHz. Just observe how slow the AVR is.
GCC 4.7.4 (Atmel Studio GNU 5.4.0) -O3
___ __ ___ ___
/ _ \ / |/ // _ \ Simple real-time kernel
/ , _// /|_/ // ___/ Standard benchmark test
/_/|_|/_/ /_//_/
====================================================
Test (number in CPU cycles) : AVG / MAX / MIN
Yield : 437 / 739 / 437
Mailbox : 751 / 1036 / 734
Semaphore : 717 / 1003 / 701
FIFO : 314 / 609 / 307
Message queue : 1098 / 1375 / 1073
Blocking message queue : 1352 / 1623 / 1321
Memory allocation/free pair : 1680 / 1809 / 1558
ISR Mailbox : 637 / 922 / 620
ISR Semaphore : 639 / 924 / 622
ISR Message queue : 921 / 1198 / 896
ISR Blocking message queue : 1087 / 1361 / 1059
GCC 4.7.4 (Atmel Studio GNU 5.4.0) -Os -mcall-prologues
___ __ ___ ___
/ _ \ / |/ // _ \ Simple real-time kernel
/ , _// /|_/ // ___/ Standard benchmark test
/_/|_|/_/ /_//_/
====================================================
Test (number in CPU cycles) : AVG / MAX / MIN
Yield : 428 / 705 / 428
Mailbox : 793 / 1054 / 777
Semaphore : 740 / 1002 / 725
FIFO : 314 / 585 / 308
Message queue : 1193 / 1445 / 1168
Blocking message queue : 1522 / 1767 / 1490
Memory allocation/free pair : 2220 / 2354 / 2097
ISR Mailbox : 671 / 931 / 654
ISR Semaphore : 634 / 895 / 618
ISR Message queue : 944 / 1198 / 921
ISR Blocking message queue : 1132 / 1382 / 1105
******************************************************************************/

/* Include *******************************************************************/
Expand Down Expand Up @@ -44,6 +83,10 @@ Return : None.
void Timer_Init(void)
{
/* TIM1 clock = CPU clock */
TCCR1A=0x00U;
TCCR1B=0x01U;
TCCR1C=0x00U;
TCNT1=0x0000U;
}
/* End Function:Timer_Init ***************************************************/

Expand All @@ -57,11 +100,18 @@ Return : None.
void Int_Init(void)
{
/* TIM2 clock = 1/256 CPU clock */
TCNT2=0x00U;
OCR2A=100U;
TIFR2=0x00U;
TCCR2A=0x02U;
TCCR2B=0x04U;
TIMSK2=0x02U;
}

/* The interrupt handler */
void TIM2_Handler(void)
{
TIFR2=0x00U;
Int_Handler();
}
/* End Function:Int_Init *****************************************************/
Expand All @@ -75,7 +125,7 @@ Return : None.
******************************************************************************/
void Int_Disable(void)
{

TIMSK2=0x00U;
}
#endif
/* End Function:Int_Disable **************************************************/
Expand Down
Loading

0 comments on commit 50f39cc

Please sign in to comment.