/**************************************************************************//**
 * @item     CosyOS-III Config
 * @file     mcucfg_80251.h
 * @brief    80251 Core Config File
 * @author   迟凯峰
 * @version  v3.0.0
 * @date     2026.07.21
 ******************************************************************************/

#ifndef __MCUCFG_80251_H
#define __MCUCFG_80251_H

///////////////////////////////////////////////////////////////////////////////

          //*** <<< Use Configuration Wizard in Context Menu >>> ***//

///////////////////////////////////////////////////////////////////////////////
// <o> 系统时钟频率
// <i> 告知CosyOS您所配置的系统时钟，单位即可为赫兹（HZ）也可为兆赫（MHZ），需输入整数。
// <i> 例如系统时钟为24MHZ，您即可输入24000000，也可输入24。
// <i> 如果系统时钟为11.0592MHZ，仅能输入11059200。
#define __MCUCFG_SYSCLK                 24

///////////////////////////////////////////////////////////////////////////////
// <o> 任务队列内存
// <1=> data <2=> edata <3=> xdata
// <i> 任务队列内存，会对任务调度性能产生显著影响，建议尽量配置在DATA或EDATA中。
#define __MCUCFG_MEMORY_TASKQUE         2

///////////////////////////////////////////////////////////////////////////////
// <o> 内存方案配置
// <0=> 方案一：PSP; XSmall; near static & malloc
// <1=> 方案二：MSP; XSmall; near static & malloc
// <2=> 方案三：MSP; XSmall; near static, xdata malloc
// <3=> 方案四：MSP; Large; xdata static, near malloc
// <4=> 方案五：MSP; Large; xdata static & malloc
// <i> 任务栈模式；Memory Model；内核对象内存
// <i> 注意事项：
// <i> 1、编译器的 Memory Model 设置，务必要与所选方案保持一致。
// <i> 2、内存池指针均采用相对地址（0起始）。
#define MCUCFG_MEMORYMODEL              0

///////////////////////////////////////////////////////////////////////////////
// <h> PendSV中断配置
// <i> 您可选择一个未使用的硬件中断，做为PendSV软中断，用于执行系统的挂起服务。
// <i> 还需在初始化钩子中配置该中断，确保它不会被硬件触发，中断优先级必须为最低级。

// <o> 中断向量地址
// <i> 中断向量地址
#define MCUCFG_PENDSV_VECTORADDR        0003H

// <o> 中断开启
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：EX0 = 1
#define mPendSV_Enable()                EX0 = 1

// <o> 中断关闭
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：EX0 = 0
#define mPendSV_Disable()               EX0 = 0

// <o> 中断触发（置中断标志位）
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：IE0 = 1
#define mPendSV_Set()                   IE0 = 1

// <o> 中断清零（清中断标志位）
// <i> 此项您应在文本编辑界面中定义，必须使用汇编代码。
// <i> 即使该标志位能够在中断服务程序中硬件自动清零，仍建议用户不要省略，以确保其可靠清零。
// <i> 示例：CLR IE0
#define mPendSV_Clear                   CLR IE0

// </h>
///////////////////////////////////////////////////////////////////////////////
// <o> 中断FIFO服务装载器-互斥访问方案
// <256=> [JBC]指令 <255=> [INC]指令 <0=> 关闭总中断
// <i> ------------------------------------------------------------------------
// <i> [JBC]指令
// <i> 适用于所有80251内核，可实现全局不关总中断、零中断延迟。
// <i> 适用于FIFO服务持续并发量较小的情况。
// <i> PendSV_FIFO深度最大值：40
// <i> ------------------------------------------------------------------------
// <i> [INC]指令
// <i> 适用于所有80251内核，可实现全局不关总中断、零中断延迟。
// <i> 适用于FIFO服务持续并发量较大的情况。
// <i> PendSV_FIFO深度最大值：127
// <i> ------------------------------------------------------------------------
// <i> 关闭总中断
// <i> 适用于所有80251内核，并具有极短的、确定的关闭总中断时间，
// <i> 包括关闭总中断、再次开启总中断在内，共8个机器周期。
// <i> 内核关闭总中断仅发生在 port_80251s.s > mPendSV_FIFOPreempt 中。
// <i> 适用于FIFO服务持续并发量较大的情况。
// <i> PendSV_FIFO深度最大值：127
#define MCUCFG_PENDSVFIFO_MUTEX         256

///////////////////////////////////////////////////////////////////////////////
// <h> 动态内存设置
// <i> CosyOS会使用下列参数自动初始化内存池。

// <o> 内存池指针
// <i> 内存池的起始内存地址
#define MCUCFG_MALLOCMEMBPTR            3072

// <o> 内存池大小（Bytes）
// <i> 内存池大小，单位为字节数
#define MCUCFG_MALLOCMEMSIZE            1024

// </h>
///////////////////////////////////////////////////////////////////////////////
// <q> 系统变量零安装
// <i> 部分系统变量需要初始化为0，否则系统可能会运行异常，这些变量可能存储在任何物理内存区域；
// <i> 如果未能在启动文件中正确配置全部内存清零，应开启该选项，系统在定义变量时会自动赋值为0。
#define MCUCFG_OSZEROINSTALL            1

///////////////////////////////////////////////////////////////////////////////
// <o> 任务切换模式
// <0=> 节约FLASH <1=> 卓越性能
// <i> 当任务栈模式为MSP模式，即内存方案二~五，任务切换时的搬栈效率。
#define MCUCFG_TASKSWITCHMODE           0

///////////////////////////////////////////////////////////////////////////////
// <h> 任务切换现场保护
// <i> 用户自定义任务切换现场保护
// <i> CosyOS在任务切换时，默认自动保存的寄存器：{4 Byte Interrupt Frame,DR28-DR0,DR56,PSW1,PSW}。
// <i> 如您需要额外增加对其它寄存器的现场保护，可配置下面的选项。
// <i> 您可选择用C语言或汇编语言来写现场保护的代码，应用非常灵活。

// <q> C语言保护方案
// <i> 是否启用C语言保护方案？
// <i> 下方各定义项已经直接给出示例（保护/恢复：DPH1、DPL1、DPS），直接在文本编辑界面中修改即可。
#define __MCUCFG_USERREGSAVE_C          0

#if (__MCUCFG_USERREGSAVE_C == 1)

// 定义用于现场保护的数组
// 定义一个"unsigned char"类型的数组，结尾必须加语句结束符";"。
#define mUserReg_DEFc_ \
	unsigned char user_reg[3];

// 定义保护现场代码
// 用c语言代码，将相应寄存器的内容拷贝至自定义的数组中。
#define mUserReg_SAVEc() \
do{ \
	s_task_current->user_reg[0] = DPH1; \
	s_task_current->user_reg[1] = DPL1; \
	s_task_current->user_reg[2] = DPS; \
}while(false)

// 定义恢复现场代码
// 用c语言代码，将自定义数组中的数据恢复至相应的寄存器。
#define mUserReg_RESc() \
do{ \
	DPH1  = node_news->user_reg[0]; \
	DPL1  = node_news->user_reg[1]; \
	DPS   = node_news->user_reg[2]; \
}while(false)

// 寄存器数据初始化
// 用c语言代码，初始化自定义数组中的寄存器数据。
#define mUserReg_INITc() \
do{ \
	node_news->user_reg[0] = DPH1; \
	node_news->user_reg[1] = DPL1; \
	node_news->user_reg[2] = DPS; \
}while(false)

#endif

// <e> 汇编语言保护方案
// <i> 是否启用汇编语言保护方案？
// <i> 需先配置下面的选项，而后在 mcucfg_80251.inc 文件中写代码。
#define __MCUCFG_USERREGSAVE_ASM        0

#if (__MCUCFG_USERREGSAVE_ASM == 1)

// <o> 用户寄存器SIZE
// <i> 定义现场保护的用户寄存器的总字节数。
#define MCUCFG_USERREGSIZE              3

// 寄存器数据初始化
// 用c语言代码，初始化任务栈中的寄存器数据。
#define mUserReg_INITa() \
do{ \
	*(s_u8_t *)(mUserReg_Addr + 0) = DPH1; \
	*(s_u8_t *)(mUserReg_Addr + 1) = DPL1; \
	*(s_u8_t *)(mUserReg_Addr + 2) = DPS; \
}while(false)

#endif
// </e>
// </h>
///////////////////////////////////////////////////////////////////////////////

                //*** <<< end of configuration section >>> ***//

///////////////////////////////////////////////////////////////////////////////

#ifndef __MSP__
#define __MSP__   1 // MSP模式
#endif
#ifndef __PSP__
#define __PSP__   2 // PSP模式
#endif

#if   (__MCUCFG_SYSCLK && __MCUCFG_SYSCLK <= 255)
#define MCUCFG_SYSCLK   (__MCUCFG_SYSCLK / 1UL)
#define MCUCFG_SYSCLKHZ (__MCUCFG_SYSCLK * 1000000UL)
#elif (__MCUCFG_SYSCLK >= 1000000UL)
#define MCUCFG_SYSCLK   (__MCUCFG_SYSCLK / 1000000UL)
#define MCUCFG_SYSCLKHZ (__MCUCFG_SYSCLK * 1UL)
#else
#error 参数非法 of 系统时钟！
#endif

  #if (__MCUCFG_MEMORY_TASKQUE == 1)
#define _QUE_MEM_ data
#elif (__MCUCFG_MEMORY_TASKQUE == 2)
#define _QUE_MEM_ edata
#else
#define _QUE_MEM_ xdata
#endif

#if (MCUCFG_MEMORYMODEL == 0)
#define MCUCFG_TASKSTACK_MODE __PSP__
#else
#define MCUCFG_TASKSTACK_MODE __MSP__
#endif

#if (!__MCUCFG_USERREGSAVE_C)
#define mUserReg_DEFc_
#define mUserReg_SAVEc()
#define mUserReg_RESc()
#define mUserReg_INITc()
#endif

#if (!__MCUCFG_USERREGSAVE_ASM)
#define MCUCFG_USERREGSIZE  0
#define mUserReg_INITa()
#else
#define mUserReg_Addr (node_news->bsp + 42)
#endif


#endif
